Skip to content

Consolidate scattered PSModule action repositories into Process-PSModule #384

Description

Process-PSModule is a set of reusable workflows that call composite actions to plan, build, test, document, and publish PowerShell modules. Those composite actions have historically lived in their own repositories (Get-PSModuleSettings, Resolve-PSModuleVersion, Build-PSModule, Test-PSModule, Publish-PSModule, Install-PSModuleHelpers, Document-PSModule, Get-PesterCodeCoverage, Get-PesterTestResults), each pinned separately by Process-PSModule's workflows and versioned on its own release cadence.

Request

Desired capability

A single change to the framework should require a single PR and a single release — not a coordinated set of releases and pin bumps across the framework's action repositories and 14+ consumer repositories.

Current experience

Each action repo is versioned independently, requires a separate pin in Process-PSModule's workflows, and maintains its own CI and test fixtures. When the framework changes, the change has to propagate through 3+ action releases and pin bumps before it reaches consumers, and test fixtures for the same testing concerns are duplicated across repos.

Acceptance criteria

  • All framework logic lives in one repository (Process-PSModule), under .github/actions/<Action>/.
  • Consumers automatically get the actions matching the workflow version they reference — no separate action repo lookups or pins.
  • Test fixtures are colocated with the logic they exercise (addresses Consolidate test fixtures into a shared repository for all -PSModule actions #347).
  • Existing consumers' interface is unchanged — inputs, outputs, and secrets stay the same; only the internal invocation method changes.
  • The scattered action repositories are archived and deleted once migration is complete.
  • There is no separate action versioning — Process-PSModule's version is the framework version.

Technical decisions

Consolidate all framework actions into Process-PSModule, not a separate PSMA library. Actions are internalized as subfolders (.github/actions/<Action>) and invoked via local relative paths, after each workflow checks out its own source.

Self-checkout mechanism: each stage workflow adds a checkout step for Process-PSModule itself, using job.workflow_repository and job.workflow_sha — context properties that let a reusable workflow discover the repository and commit it is being invoked from:

- name: Checkout Process-PSModule
  uses: actions/checkout@v7
  with:
    repository: ${{ job.workflow_repository }}
    ref: ${{ job.workflow_sha }}
    path: _wf

- name: Build module
  uses: ./_wf/.github/actions/Build-PSModule
  with:
    ...

Local action references don't support an @ref suffix, so the actions are invoked as plain relative paths (./_wf/.github/actions/<Action>) — the checkout step above is what pins them to the right commit, not the uses: line.

Note

job.workflow_repository and job.workflow_sha did not exist before. GitHub added them in April 2026 (actions/runner#4335, shipped in Actions Runner v2.334.0) — no dedicated GitHub changelog announcement was found; the runner release and the job context reference are the primary sources. This is what makes internalization practical: without it, every consumer would need to check out a specific tag or SHA of Process-PSModule by hand.

Why internalize instead of a separate PSMA library:

Structure (as implemented):

Process-PSModule/
  .github/
    actions/
      Install-PSModuleHelpers/
      Get-PSModuleSettings/
      Resolve-PSModuleVersion/
      Build-PSModule/
      Test-PSModule/
      Get-PesterCodeCoverage/
      Get-PesterTestResults/
      Document-PSModule/
      Publish-PSModule/
      Initialize-PSModule/
    workflows/
      Plan.yml
      Build-Module.yml
      Test-Module.yml
      Publish-Module.yml
      Release.yml
      ...
  tests/
    srcTestRepo/
    srcWithManifestTestRepo/

Test-PSModule, Get-PesterCodeCoverage, and Get-PesterTestResults stay as three separate action folders rather than merging into one — they're invoked from different workflow stages and merging them would have coupled unrelated concerns.

Initialize-PSModule was added during internalization; it wasn't part of the original scattered-repo set but follows the same pattern.

GitHub-Script, Invoke-Pester, and Invoke-ScriptAnalyzer remain external, pinned at commits as before — they are general-purpose actions, not part of the PSModule framework itself.

Metadata

Metadata

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions