Releases: PSModule/Process-PSModule
Release list
v8.0.3
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/Prereleaseselect Pester, whileGitHubVersion/GitHubPrereleaseselect 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.ShuffleRun.ShuffleSeedRun.ParallelRun.ParallelThrottleLimitDebug.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_ShuffleRun_ShuffleSeedRun_ParallelRun_ParallelThrottleLimitDebug_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.ymlimports 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.psd1andsrc/data/Settings.psd1) are not implicitly loaded and are currently unused. Any future PSD1 dataset test must callImport-PowerShellDataFileexplicitly or load it from supported setup. Expose-TestDatapasses only explicit caller-provided fixtures as environment variables to setup, teardown, and tests.- Module linting remains a separate
Invoke-ScriptAnalyzerjob 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 --checkpassed.
Commits: 337533c, ad2961e, 8c3366f, 0423d6a
v8.0.2
🪲 [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: writeTechnical details
- Removed legacy
github.tokenwrite 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
v8permission 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 |
v8.0.1
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
- skip running unsafe pr check if input is default by
@aiqiaoyin actions/checkout#2518- trim only ascii whitespace for branch by
@aiqiaoyin actions/checkout#2521- escape values passed to --unset by
@aiqiaoyin actions/checkout#2530- Various dependency updates
Full Changelog: actions/checkout@v7...v7.0.1
Changelog
Sourced from actions/checkout's changelog.
Changelog
v7.0.1
- Skip running unsafe pr check if input is default by
@aiqiaoyin actions/checkout#2518- Trim only ascii whitespace for branch by
@aiqiaoyin actions/checkout#2521- Escape values passed to --unset by
@aiqiaoyin actions/checkout#2530- Various dependency updates
v7.0.0
- Block checking out fork PR for pull_request_target and workflow_run by
@aiqiaoyin actions/checkout#2454- Various dependency updates
v6.0.3
- Fix checkout init for SHA-256 repositories by
@yaananthin actions/checkout#2439- fix: expand merge commit SHA regex and add SHA-256 test cases by
@yaananthin actions/checkout#2414v6.0.2
- Fix tag handling: preserve annotations and explicit fetch-tags by
@ericsciplein actions/checkout#2356v6.0.1
- Add worktree support for persist-credentials includeIf by
@ericsciplein actions/checkout#2327v6.0.0
- Persist creds to a separate file by
@ericsciplein actions/checkout#2286- Update README to include Node.js 24 support details and requirements by
@salmanmkcin actions/checkout#2248v5.0.1
- Port v6 cleanup to v5 by
@ericsciplein actions/checkout#2301v5.0.0
- Update actions checkout to use node 24 by
@salmanmkcin actions/checkout#2226v4.3.1
- Port v6 cleanup to v4 by
@ericsciplein actions/checkout#2305v4.3.0
- docs: update README.md by
@motssin actions/checkout#1971- Add internal repos for checking out multiple repositories by
@mouismailin actions/checkout#1977- Documentation update - add recommended permissions to Readme by
@benwellsin actions/checkout#2043- Adjust positioning of user email note and permissions heading by
@joshmgrossin actions/checkout#2044- Update README.md by
@nebuk89in actions/checkout#2194- Update CODEOWNERS for actions by
@TingluoHuangin actions/checkout#2224- Update package dependencies by
@salmanmkcin actions/checkout#2236v4.2.2
url-helper.tsnow leverages well-known environment variables by@jww3in actions/checkout#1941- Expand unit test coverage for
isGhesby@jww3in actions/checkout#1946v4.2.1
- Check out other refs/* by commit if provided, fall back to ref by
@orhantoyin actions/checkout#1924
... (truncated)
Commits
- See full diff in compare view
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
- Migrate to ESM and upgrade dependencies by
@priyagupta108in actions/setup-python#1330- Pin SHA commits and update docs with latest versions by
@HarithaVattikutiin actions/setup-python#1338- Remove the pip-install input by
@gowridurgadin actions/setup-python#1336Bug Fix
- Fix to Classify stderr warning messages as warnings instead of errors in annotations by
@lmvysakhin actions/setup-python#1335- Validate and retry manifest fetch to prevent silent failures by
@priyagupta108in actions/setup-python#1332Dependency Upgrade
- Bump certifi from 2020.6.20 to 2024.7.4 in /tests/data by
@dependabotin actions/setup-python#1328- Remove EOL Python versions and Bumps numpy text fixture by
@priya-kinthaliin actions/setup-python#1333- Upgrade
@actions/cacheto 6.2.0 by@philip-gaiin actions/setup-python#1337New Contributors
@lmvysakhmade their first contribution in actions/setup-python#1335@philip-gaimade their first contribution in acti...
v8.0.0
🌟 [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 configuredAutoPatchingbehavior. - 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.closedevent 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: falseto 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.Skipprevents 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}/pullsand 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.Skipseparates site build from deployment; dogfood callers mark their fixture roots as important, build site artifacts, and skip real Pages publication.
Related issues
- Fixes #390
- Related: #438
- Dependency: PSModule/Release-GHRepository#108
v7.0.0
🌟 [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 nogithub.tokenfallback. - 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
⚙️ [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.FullVersionis passed directly toRelease-PSModuleas the GitHub release tag. Release-PSModuledetects 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
WhatIfbehavior and resuming an existing release without recreating it. Full live publishing remains intentionally out of scope.
Related issues
v6.1.19
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
⚙️ [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/checkoutv7.0.1 commit3d3c42e5aac5ba805825da76410c181273ba90b1. - Applied
persist-credentials: falseto all 28 checkout steps. - Configured
USE_FIND_ALGORITHM: truefor the Super-Linter invocations inLinter.yml,Lint-Repository.yml, andBuild-Docs.yml. - Removed
DEFAULT_BRANCHfrom the local documentation Super-Linter invocation. - Restricted
Build-Docs.ymldocumentation linting tooutputs/docsMarkdown files withFILTER_REGEX_INCLUDE. - Removed all
fetch-depth: 0settings; checkout now uses the action's shallow fetch default. - Updated the previously missed
.github/workflows/Test-Actions.ymlreference. - 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
🪲 [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 bound2.0.0and1.2.*to1.3.0; concrete maximum versions remain inclusive. - Source test fixtures now exercise a
ThreadJobrequirement withModuleVersion = '1.0.0'andMaximumVersion = '1.*'. - The branch was synchronized with
main; the repository's native Zensical workflow remains unchanged and continues to build directly fromzensical.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)
- Fixes #444
v6.1.16
🪲 [Fix]: Release tags keep the configured version prefix (#440)
Releases created by the module pipeline are tagged with the version prefix configured in .github/PSModule.yml again. A repository that keeps the default VersionPrefix: 'v' is tagged v1.1.10, not 1.1.10, and its prereleases are tagged v1.1.11-mybranch001. A repository that sets VersionPrefix: '' keeps its unprefixed tags exactly as before.
Fixed: release tags no longer lose the configured version prefix
Since v6 the release tag was built from the compiled manifest's ModuleVersion alone. That value is Major.Minor.Patch by definition, so the prefix had nowhere to live and every repository publishing on v6 with the default prefix picked up a tag that did not match its own history — PSModule/Toml went from v0.0.1 to 0.0.2, PSModule/Domeneshop from v0.0.2 to 1.0.0, PSModule/PSSemVer from v1.1.9 to 1.1.10.
Nothing needs to change in a module repository. The prefix is read from the setting that already exists:
Publish:
Module:
VersionPrefix: 'v' # default; set to '' for unprefixed tagsThe prefix applies to the GitHub release tag and to nothing else. A PowerShell module manifest's ModuleVersion and a PowerShell Gallery package version only accept plain SemVer, so the version published to the Gallery, the version in the Gallery link, and the name of the module zip attached to the release all stay unprefixed. With VersionPrefix: 'v' a release looks like this:
| Value | |
|---|---|
| GitHub release tag and title | v1.1.10 |
| PowerShell Gallery version | 1.1.10 |
Manifest ModuleVersion |
1.1.10 |
| Attached artifact | MyModule-1.1.10.zip |
Repositories that already published an unprefixed tag on v6 keep it. Those releases are public, their artifacts are linked from the release pages, and the PowerShell Gallery listing points at them, so they are left alone and the prefix resumes from the next release. An unprefixed tag left in the history does not affect future version resolution.
Technical details
What changed
.github/actions/Publish-PSModule/src/Publish-PSModule.Helpers.psm1— new action-scoped helper module withGet-ModuleVersionString, which composes the module's SemVer string, andGet-ReleaseTag, which prefixes it..github/actions/Publish-PSModule/src/publish.ps1— reads the newVersionPrefixinput, derives both version strings from those helpers in one place, and reports both in the resolved-version summary and the closing log line..github/actions/Publish-PSModule/action.yml— new optionalVersionPrefixinput, defaulting to''..github/workflows/Publish-Module.yml— passesSettings.Publish.Module.VersionPrefixinto the action..github/actions/Publish-PSModule/tests/Publish-PSModule.Helpers.Tests.ps1— new Pester suite, picked up automatically by the existingTest-Actionsdiscovery over.github/actions/*/tests.
Five files, all on the tag-derivation path. No test fixture or pipeline behaviour outside it changes.
Approach
The manifest stays the source of the numeric version. ModuleVersion is what was built, tested, and pushed to the Gallery, so the tag has to agree with it — the ^\d+\.\d+\.\d+$ guard and the 999.0.0 placeholder check are unchanged. Only the prefix, the one piece of the tag the manifest cannot carry, is taken from the settings the Plan job already resolves. Composing the two is equivalent to using Resolution.FullVersion in the normal case and stays anchored to the artifact if the two ever disagree.
Keeping the prefix off the module version. publish.ps1 previously built the Gallery version with its own copy of the prerelease composition, independent of the tag. Two independent implementations of the same string is how they drift, and drift in this direction means a prefixed version reaching Publish-PSResource. Both now come from Get-ModuleVersionString; Get-ReleaseTag is that string with the prefix in front, so the prefix is the only possible difference between them, by construction rather than by convention.
The prefix reaches: the release tag, the release title fallback, the gh release upload target, the release URL, the GitHub half of the pull request comment, and PSMODULE_PUBLISH_PSMODULE_CONTEXT_ReleaseTag for cleanup. It reaches nothing else. publish.ps1 never writes to the manifest — it is read-only on the artifact by design — and Build-PSModule stamps the manifest from Resolution.Version and Resolution.Prerelease, which are unprefixed. Resolution.FullVersion, the one prefix-bearing value in the Settings object, is consumed by no downstream job.
Get-ModuleVersionString and Get-ReleaseTag both trim their inputs, because prefix and label arrive through environment variables, and both treat a whitespace-only prerelease label as a stable release.
Verification — unit tests, red then green in CI
| Commit | Change | Test actions |
|---|---|---|
fd2c7d9 |
Extract tag derivation into a helper, no behavior change | success |
d0f8f7a |
Add the regression test | failure (13 of 15) |
06b4714 |
Apply the configured version prefix | success (15 of 15) |
32 cases now. Alongside the prefixed and unprefixed tag shapes, absent and null prefixes, whitespace normalization, and the tag shape Cleanup-PSModulePrereleases depends on, a the prefix reaches the release tag and nothing else context pins the separation directly:
- for five prefix/version/label combinations, the tag equals
$Prefix+ the module version string; - the module version string never begins with the prefix and always matches
^\d+\.\d+\.\d+(-[0-9A-Za-z\-.]+)?$; Get-ModuleVersionStringhas noVersionPrefixparameter at all, so a caller cannot pass one;- an unprefixed repository gets two identical strings, and stripping
vfrom a prefixed tag returns the module version string.
Verification — the wiring, observed once in CI on an interim commit
This bug was a wiring failure, not a logic failure. VersionPrefix was resolved correctly by the Plan job and present in the Settings JSON; it simply never reached the tag. Unit tests prove the helpers compose correctly given the right input — they cannot prove that fromJson(inputs.Settings).Publish.Module.VersionPrefix → action input → PSMODULE_PUBLISH_PSMODULE_INPUT_VersionPrefix → $versionPrefix delivers the value.
Publish-Module is skipped at the job level in every self-test run — Publish.Module.Enabled is (ReleaseType -ne 'None') -or shouldAutoCleanup, and an open pull request satisfies neither without a prerelease label — so the self-test does not exercise that chain on this diff.
To close that gap once, an interim commit on this branch added Fix to a fixture's PrereleaseLabels, which made the self-test run the publish path under WhatIf. That commit has since been reset and is not part of this pull request; the observation below is from run 30759608449 and is reported as a one-time measurement, not as coverage this change carries forward.
Module name: [PSModuleTest]
Version prefix: [v]
WhatIf: [True]
ModuleVersion : 6.1.16
VersionPrefix : v
Prerelease : fixversionprefixreleasetag001
CreatePrerelease : True
ReleaseTag : v6.1.16-fixversionprefixreleasetag001
WhatIf: gh release create v6.1.16-fixversionprefixreleasetag001 --title v6.1.16-fixversionprefixreleasetag001 --notes-file /tmp/tmpjar7Eu.tmp --target fix-version-prefix-release-tag --prerelease
Nothing was published in that run: Publish-PSResource was logged rather than executed, no release or tag was created, and the Release workflow on the same push reported Create a prerelease: [False] / Skipping release creation.
Standing publish-path coverage in CI is the subject of #436.
Verification — locally, outside CI
publish.ps1 run end to end in WhatIf mode against a fabricated artifact, all four combinations, re-run after the separation change. Every line below is from those runs:
| Prefix | Prerelease | Gallery version | Release tag | Artifact | Exported …_CONTEXT_ReleaseTag |
|---|---|---|---|---|---|
v |
— | 1.1.10 |
v1.1.10 |
PSModuleTest-1.1.10.zip |
v1.1.10 |
v |
mybranch001 |
1.1.11-mybranch001 |
v1.1.11-mybranch001 |
PSModuleTest-1.1.11-mybranch001.zip |
v1.1.11-mybranch001 |
'' |
— | 1.1.10 |
1.1.10 |
PSModuleTest-1.1.10.zip |
1.1.10 |
'' |
mybranch001 |
1.1.11-mybranch001 |
1.1.11-mybranch001 |
PSModuleTest-1.1.11-mybranch001.zip |
1.1.11-mybranch001 |
The first row is the PSModule/PSSemVer case from the bug report, which produced tag 1.1.10 before this change. The Gallery link and comment carried the unprefixed version in every run:
Publishing complete. PowerShell Gallery version: [1.1.10]. GitHub release tag: [v1.1.10].
gh pr comment 42 -b '✅ New release: PowerShell Gallery - [PSModuleTest 1.1.10](https://www.powershellgallery.com/packages/PSModuleTest/1.1.10)'
AutoCleanup was verified the same way, running cleanup.ps1 against fixture release lists with the gh CLI shadowed. It keys off tagName -like "*$prereleaseName*", which is prefix-agnostic, and excludes the published release by comparing tagName to PSMODULE_PUBLISH_PSMODULE_CONTEXT_ReleaseTag, which is now prefixed on both sides:
| Repository | Published tag | Deleted | Excluded |
|---|---|---|---|
| Prefixed | v1.1.11-mybranch003 |
v1.1.11-mybranch002, v1.1.11-mybranch001 |
published tag, v1.1.10, another branch's prerelease |
| Unprefixed | 1.1.11-mybranch003 |
1.1.11-mybranch002, 1.1.11-mybranch001 |
published tag, 1.1.10, another branch's prerelease |
| Mixed history — unprefixed leftovers from v6 | v1.1.11-mybranch003 |
`1.1.... |