Repository navigation
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:
- Simpler checkout:
job.workflow_shameansProcess-PSModuleself-checks out at the invoking job's commit; local relative paths resolve directly without a second action repository lookup. - No second versioning: actions live in
Process-PSModule's version space; there's no separate action release cadence to coordinate. - Unified test fixtures: all tests and fixtures colocate with the logic. Eliminates drift (Consolidate test fixtures into a shared repository for all -PSModule actions #347).
- One place for routing logic: event → release decision lives in a single dispatcher (related: Support running the workflow on push to main, with prerelease-only-during-open-PR model #390, for the push-to-main prerelease model — tracked separately from internalization).
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.
Activity
[-]Consolidate framework scripts into the PSMA action library, then move stable releases to push-to-main[/-][+]Consolidate scattered PSModule action repositories into Process-PSModule[/+]