Skip to content

Releases: PSModule/Process-PSModule

v8.0.4

Choose a tag to compare

@github-actions github-actions released this 02 Sep 08:11
68696b6

🪲 [Fix]: New module versions publish to the PowerShell Gallery (#529)

A module version that has never been published to the PowerShell Gallery can now be published. Any first release, and every subsequent new version, previously failed the Publish-Module stage before the upload was attempted.

Fixed: New module versions publish to the PowerShell Gallery

Publishing a version that is not yet on the PowerShell Gallery now succeeds. The stage checks whether the version already exists so an interrupted run can resume, and treats an absent version as the expected result for a new release rather than an error.

Before this change the Publish-Module job failed with the following, and no module was ever uploaded:

Find-PSResource: Package with name 'MyModule', version '1.3.1' could not be found in repository 'PSGallery'.
Error: Process completed with exit code 1.

No repository configuration changes are needed. A workflow run that previously failed at this point succeeds on re-run.

Resuming an interrupted publication is unchanged: when the version is already on the Gallery, the run skips the upload and continues to GitHub release creation.


Technical details
  • .github/actions/Publish-PSModule/src/publish.ps1 — the Gallery existence probe in the Publish to PSGallery region ran Find-PSResource with -ErrorAction Stop. Microsoft.PowerShell.PSResourceGet raises PackageNotFound,Microsoft.PowerShell.PSResourceGet.Cmdlets.FindPSResource when the requested version does not exist, which -ErrorAction Stop turns into a throw, so the probe made a missing version fatal instead of returning $null. The probe now keeps -ErrorAction Stop and catches only PackageNotFound, treating that one error as 'not yet published' and letting the if ($publishedPackage) branch decide the outcome. Every other error stays fatal, so a transient Gallery failure cannot be misread as 'version absent' and cause a re-upload of a version that already exists.
  • The probe was introduced in #512 to make Gallery publication idempotent for the default-branch push release path. That path replaced a try/catch around Publish-PSResource, which is why the regression reached main without an existing test catching it.
  • .github/actions/Publish-PSModule/tests/Publish-PSModule.Recovery.Tests.ps1 — the harness could not observe whether publication happened, so its assertions were vacuous: Publish-PSResource was shimmed to set $script:publishInvoked, but publish.ps1 runs in its own scope via &, so the flag never propagated and stayed $false regardless. Replaced with a hashtable captured by GetNewClosure(), which is shared by reference. A second variant wrote a marker file under $env:GITHUB_WORKSPACE; that is process-wide and races between parallel Pester runspaces, so the marker could land in another test file's TestDrive. The not-found shim also used $PSCmdlet.ThrowTerminatingError(...), which ignores -ErrorAction and therefore threw under both Stop and SilentlyContinue — unable to distinguish the fix from the defect. It now uses Write-Error with the real PackageNotFound error ID, matching how the cmdlet actually behaves. Added a case asserting a non-PackageNotFound lookup failure stays fatal and does not publish. Each test was verified to fail against the specific defect it guards.
  • .github/actions/Release-PSModule/tests/Release-PSModule.WhatIf.Tests.ps1 and Publish-PSModule.Recovery.Tests.ps1 — shim teardown used Remove-Item -Path function:global:X. Set-Item accepts that path and creates X in the global scope, but Remove-Item and Get-Item do not resolve it back, and fail silently rather than erroring, so the cleanup was a no-op. The shims survived AfterAll and shadowed the real commands for later test files, which is what made Test-Actions fail with A parameter cannot be found that matches parameter name 'Prerelease' in Get-NextPrereleaseNumber. Teardown now removes by name.
  • Validated end to end in MariusStorhaug/MariusTestModule (PR #63) with the caller pointed at this branch. A new version published successfully (run 33597824748), and re-running the same job with the version present skipped the upload via the resume path (re-run). Both branches of the probe are confirmed against the live Gallery.
  • Out of scope, found while reproducing: a workflow_dispatch on the default branch resolves no associated pull request, because pull request association in .github/actions/Get-PSModuleSettings/src/main.ps1 is gated on $isPush. A manual recovery run therefore discards the merged pull request's version label and silently resolves a Patch bump. This is a separate defect in version resolution and is recorded in the analysis on #528; it is not addressed here.
  • Also out of scope: .github/workflows/Test-Actions.yml builds a Pester configuration with Run.Parallel and Run.Shuffle, asserts the options applied, then discards it and creates a fresh New-PesterConfiguration for the actual run. Parallel and shuffle are validated but never used, which is why the GITHUB_WORKSPACE race above could not surface in CI. The suite now passes both sequentially and under the intended parallel configuration, so enabling it should be safe.
Changed surface Standards checked Framework docs checked Result
.github/actions/Publish-PSModule/src/** (PowerShell) Coding standards, error handling Publish stage contract Aligned
.github/actions/Publish-PSModule/tests/** (Pester) Pester test standards Action test layout Aligned
.github/actions/Release-PSModule/tests/** (Pester) Pester test standards Action test layout Aligned
Relevant issues (or links)

Related work

v8.0.3

Choose a tag to compare

@github-actions github-actions released this 15 Aug 18:35
16419d0

Upgrade Process-PSModule to Pester 6.1 (#519)

Implemented in Process-PSModule

  • Enforce the Pester [6.1.0,7.0.0) range in reusable framework test runs.
  • Align module-local workflow inputs with the current Invoke-Pester contract: Version/Prerelease select Pester, while GitHubVersion/GitHubPrerelease select the GitHub module. Pester prerelease remains at the action default.
  • Keep the six Test-PSModule container/test files inside the action implementation at .github/actions/Test-PSModule/src/tests, because they are context-dependent framework suites executed against the compiled module or source tree. Discovery remains $PSScriptRoot/tests/$settings.
  • Add a framework CI contract test that validates Pester 6.1 configuration properties:
    • Run.Shuffle
    • Run.ShuffleSeed
    • Run.Parallel
    • Run.ParallelThrottleLimit
    • Debug.ShowStartMarkers
  • Align coverage input documentation with Pester 6.1: supported formats are JaCoCo and Cobertura, and profiler-based tracing is documented correctly.
  • Update Pester 6.1 authoring and coverage-report guidance.

Pester 6.1 runtime audit

A local Pester 6.1 probe generated a passing test result and coverage report, and the Get-PesterCodeCoverage action processed that JSON successfully. The coverage result shape remains compatible: CoveragePercent, CoveragePercentTarget, CommandsMissed, CommandsExecuted, FilesAnalyzed, and all count properties are present and consumed correctly.

The Pester result still exposes Containers; each container retains Data, Blocks, and aggregate result/count properties. The existing container files therefore remain compatible with the compiled-module/source-tree execution model.

Contract findings and required upstream follow-up

The current PSModule/Invoke-Pester v5.1.0 action does not expose these Pester configuration properties as action inputs, so this repository deliberately does not add incompatible passthrough mappings:

  • Run_Shuffle
  • Run_ShuffleSeed
  • Run_Parallel
  • Run_ParallelThrottleLimit
  • Debug_ShowStartMarkers

The coordinated PSModule/Invoke-Pester follow-up must add each input to action.yml, forward each PSMODULE_INVOKE_PESTER_INPUT_* environment variable, map them into the generated PesterConfiguration, and publish a version/tag that Process-PSModule can pin. Process-PSModule can then expose the corresponding reusable-action inputs and pass them through.

Test and fixture boundaries confirmed

  • Module-local tests assume the built module is already loaded: Test-ModuleLocal.yml imports the artifact in its prescript before invoking Pester.
  • Framework module tests import the module explicitly in their own test scopes; no implicit preload was introduced.
  • PSD1 files in the repository test fixture (src/data/Config.psd1 and src/data/Settings.psd1) are not implicitly loaded and are currently unused. Any future PSD1 dataset test must call Import-PowerShellDataFile explicitly or load it from supported setup.
  • Expose-TestData passes only explicit caller-provided fixtures as environment variables to setup, teardown, and tests.
  • Module linting remains a separate Invoke-ScriptAnalyzer job and artifact path; it is not folded into Pester execution.

Validation

  • Pester 6.1 configuration contract validated locally.
  • Pester 6.1 result/container and coverage shapes inspected locally.
  • Get-PesterCodeCoverage executed against a generated Pester 6.1 coverage JSON fixture and passed.
  • Restored Test-PSModule scripts parsed successfully.
  • Test-PSModule path resolution validated from a consumer repository root.
  • Changed PowerShell parsed successfully.
  • git diff --check passed.

Commits: 337533c, ad2961e, 8c3366f, 0423d6a

v8.0.2

Choose a tag to compare

@github-actions github-actions released this 15 Aug 17:29
bb49389

🪲 [Fix]: Obsolete GitHub token write permissions removed (#521)

Repositories that use the GitHub App permission model can run Process-PSModule without granting unneeded repository, pull-request, or status write access. GitHub Pages deployments continue to use the caller's github.token with contents: read, pages: write, and id-token: write.

Fixed: Reusable workflow permission escalation

The reusable workflow no longer requests permissions that GitHub App installation tokens already provide for release and pull-request operations. Update caller workflows to use the narrowed permission block documented for v8.

permissions:
  contents: read
  pages: write
  id-token: write

Technical details
  • Removed legacy github.token write requests from the reusable workflow and nested jobs; scoped GitHub App tokens retain repository and pull-request write access.
  • Updated repository workflow tests and caller documentation to use the v8 permission contract.
Changed surface Standards checked Framework docs checked Result
.github/workflows/** GitHub Actions Reusable workflow contract Fixed in this PR
docs/content/** Markdown, Natural Language Workflow setup guides Fixed in this PR
Relevant issues (or links)

Related work

v8.0.1

Choose a tag to compare

@github-actions github-actions released this 15 Aug 13:53
8414050

Bump the github-actions group with 2 updates (#511)

Bumps the github-actions group with 2 updates: actions/checkout and actions/setup-python.

Updates actions/checkout from 7.0.0 to 7.0.1

Release notes

Sourced from actions/checkout's releases.

v7.0.1

What's Changed

Full Changelog: actions/checkout@v7...v7.0.1

Changelog

Sourced from actions/checkout's changelog.

Changelog

v7.0.1

v7.0.0

v6.0.3

v6.0.2

v6.0.1

v6.0.0

v5.0.1

v5.0.0

v4.3.1

v4.3.0

v4.2.2

v4.2.1

... (truncated)

Commits

Updates actions/setup-python from 6.3.0 to 7.0.0

Release notes

Sourced from actions/setup-python's releases.

v7.0.0

What's Changed

Enhancements

Bug Fix

Dependency Upgrade

New Contributors

Read more

v8.0.0

Choose a tag to compare

@github-actions github-actions released this 15 Aug 10:33
5a11e8e

🌟 [Major]: Publish stable releases from default-branch pushes (#512)

Process-PSModule now authorizes stable module publication from an important push to the default branch rather than from a merged pull_request event. An associated merged pull request supplies labels and release notes only when its merge commit exactly matches the pushed SHA; direct pushes and default-branch manual dispatches release a Patch version with commit-based notes.

Breaking Changes

Caller workflows must add a push trigger for their default branch to receive stable releases. The canonical caller templates now use non-cancelling per-pull-request-or-ref concurrency so pull-request cleanup and the resulting default-branch release remain independent while all release mutations queue safely. The consumer-repository rollout remains tracked in #438.

Changed: Stable release lifecycle

  • Open labelled pull requests can publish prereleases; closed pull requests run prerelease cleanup only.
  • Important default-branch pushes run the full pipeline and publish a stable release only after PowerShell Gallery publication succeeds.
  • GitHub releases and tags target the exact tested pushed commit.
  • Direct default-branch pushes and manual dispatches default to Patch regardless of AutoPatching; pull-request prereleases retain their configured AutoPatching behavior.
  • First pushes are evaluated from the complete Git tree, and truncated trees fail explicitly rather than producing an unsafe release decision.
  • Only a real pull_request.closed event can enter cleanup; a label change on an already closed PR runs no build, prerelease, or cleanup path.
  • Release workflow concurrency uses cancel-in-progress: false to preserve serialized artifact and tag mutation.

Dogfood and documentation

  • The default and manifest dogfood callers now receive the complete PR event contract, including label changes and closure, and do not cancel release-capable runs.
  • Fixture roots are important, fixture sites build, and Publish.Site.Skip prevents deployment to the Process-PSModule Pages environment.
  • Caller, first-release, scenario, stage, settings, specification, and module-standard documentation now define default-branch push authority, cleanup-only closed PRs, direct-push behavior, and non-cancelling concurrency.

Scope boundary

Release-GHRepository@v2.0.3, which releases Process-PSModule itself, only supports pull-request event payloads. This PR therefore does not install a push trigger that would succeed without producing that repository release. Push-capable repository releases and moving workflow-consumer tags are tracked separately in PSModule/Release-GHRepository#108.

Technical Details

  • The Plan settings action normalizes PR, push, and manual-dispatch state into a shared context.
  • Push-to-PR association uses GET /repos/{owner}/{repo}/commits/{sha}/pulls and requires an exact merged commit match on the default branch.
  • Version-label conflicts remain blocking for release decisions but cannot block closed-PR cleanup.
  • Publishing, GitHub release creation, and cleanup receive the normalized PR context explicitly, so direct releases never attempt PR comments.
  • Publish.Site.Skip separates site build from deployment; dogfood callers mark their fixture roots as important, build site artifacts, and skip real Pages publication.
Related issues

v7.0.0

Choose a tag to compare

@github-actions github-actions released this 09 Aug 13:59
68a2a7f

🌟 [Major]: Reusable workflows now use GitHub App orchestration and explicit publish credentials (#408)

Process-PSModule now performs repository inspection, versioning, release management, and pull-request feedback through a configured GitHub App. Publishing uses the explicit PSGALLERY_API_KEY credential consistently from the reusable workflow through the publishing action.

Breaking Changes

Caller workflows must now pass GitHub App credentials and the PowerShell Gallery credential through the reusable workflow contract. Workflows that omit these required secrets fail before their dependent stages run.

secrets:
  PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
  GitHubAppClientId: ${{ secrets.GITHUB_APP_CLIENT_ID }}
  GitHubAppPrivateKey: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}

The caller can retain any local GitHub App secret names; only the reusable-workflow boundary names are fixed. PSGALLERY_API_KEY is also the input name of the publishing action.

Changed: Scoped GitHub automation

Every GitHub-dependent stage now mints a short-lived token for the triggering repository and requests only the access it needs. Version planning reads repository and pull-request data, builds read repository metadata, and publishing creates releases, uploads assets, cleans prereleases, and posts pull-request comments through the configured App.

The GitHub App installation needs Contents: write and Pull requests: write. Metadata: read is granted automatically. Permissions such as Actions, Statuses, Pages, and ID tokens remain part of the caller workflow's default github.token path and are not App permissions.

Technical Details

  • Plan, Build-Module, and Publish-Module mint repository-scoped installation tokens with pinned actions/create-github-app-token.
  • GitHub-facing actions receive the token only through step-scoped GH_TOKEN; the GitHub App path has no github.token fallback.
  • The release path, version resolution, repository metadata reads, settings, comments, and prerelease cleanup all use the App token.
  • The reusable workflow, publishing action input, action environment variable, and Process-PSModule documentation use PSGALLERY_API_KEY.
  • Canonical caller templates and Process-PSModule documentation include the App credential contract, PowerShell Gallery credential, permission matrix, and Dependabot configuration requirement.
  • The GitHub-Script named-token-input hardening follow-up remains tracked separately.
Related issues

v6.1.20

Choose a tag to compare

@github-actions github-actions released this 09 Aug 11:28
15c2814

⚙️ [Maintenance]: Publish and release execution paths are now decoupled (#407)

PowerShell Gallery publishing and GitHub Release creation now run as independent publish-pipeline responsibilities, so each operation reports its own outcome and a partial release can be safely retried.

Changed: Publishing and release operations are separate

Publish-PSModule now publishes the tested module artifact to PowerShell Gallery only. GitHub release creation, release notes, and release-asset upload run through the dedicated Release-PSModule action.

Technical Details

  • The Plan job remains the single version authority: Publish.Module.Resolution.FullVersion is passed directly to Release-PSModule as the GitHub release tag.
  • Release-PSModule detects an existing tag, resumes the module ZIP upload, and exports the final tag and release URL as action outputs.
  • Gallery and release steps have independent failure behavior; cleanup only runs after a successful stable release, while abandoned-PR cleanup remains supported.
  • Cleanup receives the release tag through the release action's declared output rather than shared environment state.
  • The reusable workflow now uses job-scoped write permissions and a pinned Ubuntu runner; both publishing actions have action-local READMEs.
  • Pester covers prefixed prerelease WhatIf behavior and resuming an existing release without recreating it. Full live publishing remains intentionally out of scope.
Related issues

v6.1.19

Choose a tag to compare

@github-actions github-actions released this 08 Aug 16:57
bf67cd9

Add generic missed-path coverage reporting (#421)

Summary

Adds missed-path reporting to the upstream Process-PSModule coverage flow so consumer repositories do not need repo-local post-coverage jobs.

Changes

  • Extended .github/actions/Get-PesterCodeCoverage to generate a generic missed-path report from merged coverage data.
  • Added a Missed paths section to the code coverage step summary.
  • Emit CodeCoverage-MissedPaths.md and CodeCoverage-MissedPaths.json under CodeCoverage-MissedPaths/.
  • Upload CodeCoverage-MissedPaths as an artifact in .github/workflows/Get-CodeCoverage.yml.

Notes

  • The implementation intentionally avoids repo-specific heuristics and groups misses by file path and missed line coverage.
  • Artifact upload runs with if: always() so the report is still available when coverage threshold enforcement fails.

v6.1.18

Choose a tag to compare

@github-actions github-actions released this 08 Aug 16:05
294e7b7

⚙️ [Maintenance]: GitHub Actions checkouts use least-privilege settings (#412)

GitHub Actions workflows now use the pinned actions/checkout v7.0.1 release consistently, avoid unnecessary full-history downloads, and prevent checkout credentials from persisting in the workspace. Generated documentation is linted with Super-Linter using filesystem discovery restricted to Markdown files.

Changed: Workflow checkout security and efficiency

All checkout steps disable credential persistence because these workflows do not rely on the checkout repository for authenticated Git operations. Super-Linter uses filesystem discovery instead of Git, so full-history fetching is not required.

Changed: Generated documentation lint scope

The documentation build runs Super-Linter in local mode with filesystem discovery and limits the include pattern to generated .md and .markdown files. The default branch is not configured, avoiding Git branch comparison and keeping the lint focused on the documentation output.


Technical details
  • Updated all workflow references to the pinned actions/checkout v7.0.1 commit 3d3c42e5aac5ba805825da76410c181273ba90b1.
  • Applied persist-credentials: false to all 28 checkout steps.
  • Configured USE_FIND_ALGORITHM: true for the Super-Linter invocations in Linter.yml, Lint-Repository.yml, and Build-Docs.yml.
  • Removed DEFAULT_BRANCH from the local documentation Super-Linter invocation.
  • Restricted Build-Docs.yml documentation linting to outputs/docs Markdown files with FILTER_REGEX_INCLUDE.
  • Removed all fetch-depth: 0 settings; checkout now uses the action's shallow fetch default.
  • Updated the previously missed .github/workflows/Test-Actions.yml reference.
  • Standards and framework alignment:
Changed surface Standards checked Framework docs checked Result
.github/workflows/** GitHub Actions, least privilege, dependency pinning Reusable workflow contract Aligned
Relevant issues (or links)
  • No linked issue; this is a Dependabot dependency maintenance update.

v6.1.17

Choose a tag to compare

@github-actions github-actions released this 08 Aug 15:28
169c576

🪲 [Fix]: Wildcard maximum versions no longer fail module processing (#446)

Module requirements can now use wildcard maximum versions such as 1.* without module builds or installations failing. Versions remain constrained to the requested major or minor release line, while concrete maximum versions keep their existing behavior.

Fixed: wildcard maximum versions no longer fail module builds

Module manifests can now preserve wildcard maximum-version requirements instead of rejecting them as invalid version values. A requirement such as MaximumVersion = '1.*' remains usable during manifest generation.

Fixed: wildcard maximum versions resolve to the correct release range

Module installation translates wildcard maximum versions into an exclusive upper bound. For example, MinimumVersion = '1.0.0' and MaximumVersion = '1.*' resolve to the range [1.0.0,2.0.0), allowing 1.x releases without admitting 2.x releases. Unsupported wildcard patterns are reported clearly.


Technical details
  • Manifest processing now keeps wildcard maximum versions as strings and only creates a numeric comparison bound for concrete versions.
  • Installation version-spec conversion maps 1.* to the exclusive upper bound 2.0.0 and 1.2.* to 1.3.0; concrete maximum versions remain inclusive.
  • Source test fixtures now exercise a ThreadJob requirement with ModuleVersion = '1.0.0' and MaximumVersion = '1.*'.
  • The branch was synchronized with main; the repository's native Zensical workflow remains unchanged and continues to build directly from zensical.toml.
  • Implementation plan progress: the scoped delivery bug in #444 is completed by this pull request.
Changed surface Standards checked Framework docs checked Result
.github/actions/** (PowerShell) Naming, functions, action layout Process-PSModule action conventions Aligned
tests/** (PowerShell) Pester fixture conventions Module test repository layout Aligned
Relevant issues (or links)