🌟 [Major]: Module version resolution now available as a standalone action#1
Merged
Marius Storhaug (MariusStorhaug) merged 10 commits intoMay 22, 2026
Merged
Conversation
…dd PSAvoidUsingWriteHost exclusion; suppress publishModule unused-var warning
…HUB_EVENT_PATH explicitly
…ke event into inner composite step
…data without relying on event file
Copilot started reviewing on behalf of
Marius Storhaug (MariusStorhaug)
May 22, 2026 22:19
View session
There was a problem hiding this comment.
Pull request overview
This PR converts the repository from a template action into a standalone Resolve-PSModuleVersion composite GitHub Action that computes the next module version based on settings, PR labels, GitHub releases, and PowerShell Gallery state.
Changes:
- Added a composite action contract (
action.yml) with settings-driven version resolution and outputs for version metadata. - Implemented the version resolution logic in
scripts/main.ps1, including label-based bump selection and (optional) prerelease tagging. - Added a GitHub Actions workflow to exercise common scenarios (patch/minor/major/auto-patch/ignore-label/none) and adjusted lint rules for action logging.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
action.yml |
Defines the standalone composite action interface (inputs/outputs) and runs the resolver script after installing dependencies. |
scripts/main.ps1 |
Implements version calculation and emits action outputs. |
README.md |
Replaces the template README with minimal action identification text. |
.github/workflows/Action-Test.yml |
Adds workflow-based validation jobs for several label/config scenarios. |
.github/linters/.powershell-psscriptanalyzer.psd1 |
Updates PSScriptAnalyzer exclusions to allow Write-Host in runner logs. |
Comments suppressed due to low confidence (1)
action.yml:23
- The
Debug/Verboseinputs are defined but never used by the composite steps orscripts/main.ps1, so consumers can’t actually enable debug/verbose behavior. Either wire these inputs into the script (e.g., set$DebugPreference/$VerbosePreferenceor pass flags) or remove them to keep the action contract accurate.
Debug:
description: Enable debug output.
required: false
default: 'false'
Verbose:
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Remove unused Version/Prerelease inputs (template leftovers, collide by name with Version/Prerelease outputs) - Fix PSGallery version filter: replace string -like with component comparison so 4-part versions (e.g. 1.2.3.0) match correctly - Fix PSGallery and GitHub prerelease counter casts from [int] to [long] to prevent Int32 overflow when DatePrereleaseFormat produces date-prefixed counter strings (e.g. 20260523001)
Marius Storhaug (MariusStorhaug)
added a commit
to PSModule/Build-PSModule
that referenced
this pull request
May 24, 2026
…t build time (#136) Module manifests are now stamped with the resolved version and prerelease tag at build time. The resulting artifact contains its final `ModuleVersion` (and `PrivateData.PSData.Prerelease`) before tests run, so the bytes that are tested are the bytes that ship. - Fixes PSModule/Process-PSModule#326 ## Inputs on `Build-PSModule` `Build-PSModule` now exposes new module-centric inputs: | Input | Required | Description | | --- | --- | --- | | `Name` | No | Name of the module to build. Defaults to the repository name. | | `Version` | **Yes** | Module version (`Major.Minor.Patch`) to stamp into the manifest. Build fails with a clear error when omitted or malformed. | | `Prerelease` | No | Prerelease tag (for example `mybranch001`) to stamp into `PrivateData.PSData.Prerelease`. When empty, no prerelease tag is written. | | `OutputFolder` | No | Path (relative to `WorkingDirectory`) where the built module is placed. Defaults to `outputs/module`. | Typical usage downstream of [`PSModule/Resolve-PSModuleVersion`](https://github.com/PSModule/Resolve-PSModuleVersion): ```yaml - name: Build module uses: PSModule/Build-PSModule@v5 with: Version: ${{ steps.resolve.outputs.Version }} Prerelease: ${{ steps.resolve.outputs.Prerelease }} ``` ## Breaking changes - `Version` is now **required**. Callers that previously omitted it (relying on the `999.0.0` placeholder) must now pass an explicit version in `Major.Minor.Patch` format. Builds fail immediately with a clear error when `Version` is missing or malformed. ## Technical details - `action.yml`: adds `OutputFolder` (default `outputs/module`), `Version` (`required: true`), and `Prerelease` inputs; `Name` remains optional and still defaults to the repository name. - `src/main.ps1`: reads `OutputFolder`, `Version`, and `Prerelease` from env; throws immediately when `Version` is missing or not in `Major.Minor.Patch` format. - `src/helpers/Build-PSModule.ps1`: `ModuleVersion` parameter is now `[Parameter(Mandatory)]`. - `src/helpers/Build/Build-PSModuleManifest.ps1`: `ModuleVersion` is `[Parameter(Mandatory)]`; the `999.0.0` fallback is removed — the version is assigned directly. Related PRs: - PSModule/Resolve-PSModuleVersion#1 — emits the `Version` and `Prerelease` values consumed here. - PSModule/Publish-PSModule#71 — drops its own version stamping; expects the artifact to arrive pre-stamped. - PSModule/Process-PSModule#342 — wires the workflow end-to-end.
Marius Storhaug (MariusStorhaug)
added a commit
to PSModule/Publish-PSModule
that referenced
this pull request
May 27, 2026
… before publish (#71) `Publish-PSModule` no longer calculates or mutates the module version. The artifact passed in must already contain the final `ModuleVersion` (and `Prerelease` tag, if any) stamped by the upstream build. Published GitHub Releases now include a downloadable zip of the exact module folder that was tested and pushed to the Gallery. ## Breaking Changes Version-calculation inputs have been removed. Callers must supply a pre-stamped artifact: **Removed inputs:** - `AutoPatching` - `IncrementalPrerelease` - `DatePrereleaseFormat` - `VersionPrefix` - `MajorLabels`, `MinorLabels`, `PatchLabels`, `IgnoreLabels` - `ReleaseType` **Migration:** Consumers on `PSModule/Process-PSModule` get this for free — the workflow resolves the version in the Plan job and stamps it during Build. Direct callers outside of `Process-PSModule` must use [`Resolve-PSModuleVersion`](https://github.com/PSModule/Resolve-PSModuleVersion) to compute the version and [`Build-PSModule`](https://github.com/PSModule/Build-PSModule) v5+ to stamp it before invoking this action. ## New: Module zip uploaded to GitHub Release After creating a GitHub Release, the module folder is zipped (`<Name>-<Version>.zip`) and uploaded as a release asset. The zip preserves the `<Name>/` directory structure so it can be extracted directly into a PowerShell module path. ## Changed: Cleanup only runs after stable releases The cleanup step (which removes old prerelease tags/releases) now only executes when the publish was a stable release. Previously it could inadvertently delete the just-published prerelease. Cleanup also filters on `isPrerelease` to avoid accidentally deleting stable releases whose tag happens to match the derived prerelease name. ## Technical Details - Deleted `src/init.ps1` (the old version-calculation script). - `src/publish.ps1` reads `ModuleVersion` and `Prerelease` directly from the downloaded manifest via `Import-PowerShellDataFile`, validates 3-part format, then publishes untouched via `Publish-PSResource`. - `Test-ModuleManifest` is called as advisory validation (non-terminating) since the built artifact may reference `RequiredModules` not installed on the runner. Structural validation is enforced by explicit regex guards on `ModuleVersion` and `Prerelease`. - `src/cleanup.ps1` derives the prerelease name from the PR head ref, filters on `isPrerelease`, and explicitly excludes the just-published release tag from deletion. - `action.yml` cleanup step gated on `env.PSMODULE_PUBLISH_PSMODULE_CONTEXT_IsPrerelease != 'true'`. - `GITHUB_ENV` writes use `utf8NoBOM` encoding to prevent BOM corruption. - Zip upload and temp file cleanup wrapped in `try/finally` for reliable cleanup on failure. <details><summary>Related issues</summary> - Fixes PSModule/Process-PSModule#326 - PSModule/Process-PSModule#342 - PSModule/Resolve-PSModuleVersion#1 - PSModule/Build-PSModule#136 </details>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Module version resolution is now available as a standalone action. Workflows can call it before building so the resolved version is stamped into the artifact at build time, making the bytes that are tested the bytes that ship.
New: Standalone
Resolve-PSModuleVersionactionThe action consumes the JSON
Settingsoutput fromPSModule/Get-PSModuleSettingsand emits:VersionMajor.Minor.Patchportion of the resolved version.PrereleaseFullVersionVersionPrefixand prerelease tag.ReleaseTypeRelease,Prerelease, orNonewhen no version bump label is present.CreateReleasetruewhen a release or prerelease should be created.Typical usage in the Plan job:
The action validates
Settings.Publish.Module.ReleaseType, appliesIgnoreLabelsoverrides, picks the bump type from PR labels (MajorLabels>MinorLabels>PatchLabels/AutoPatching), then computes the next version from the higher of the latest GitHub Release and the latest PowerShell Gallery version. For prereleases it appends the sanitized branch name, optionalDatePrereleaseFormattimestamp, and an incremental counter calculated from existing prereleases on the same baseline + branch.Technical Details
action.yml: composite action with inputsSettings(required JSON),Name,WorkingDirectory,Debug,Verbose,Version,Prerelease, plusEventPathandEventJson(both optional, for test overrides —EventJsontakes precedence over reading the file atEventPath). All${{ }}template expressions are isolated inenv:sections per zizmor template-injection requirements. InstallsPSModule/Install-PSModuleHelpersandPSSemVerbefore running the script.scripts/main.ps1: ports the version-resolution logic that previously lived inPublish-PSModule/src/init.ps1. Reads configuration fromPSMODULE_RESOLVE_PSMODULEVERSION_INPUT_SettingsJSON instead of separate env vars. Reads the PR event fromPSMODULE_RESOLVE_PSMODULEVERSION_INPUT_EventJsonwhen set, falling back to the file atGITHUB_EVENT_PATH. Emits outputs via$env:GITHUB_OUTPUT. Cleanup-tag discovery stays inPublish-PSModule/cleanup.ps1and is intentionally out of scope here..github/workflows/Action-Test.yml: 6 test jobs covering patch, minor, major, auto-patch, ignore-label, and None scenarios. The ignore-label job passes the fake PR event as a JSON string viaEventJsonto bypass the runner's real event file, which cannot be reliably overridden at the file-system level.README.md: replaces the template scaffold with the action's contract and usage examples.Implementation plan progress (PSModule/Process-PSModule#326):
Resolve-PSModuleVersion(LICENSE, README,action.yml,scripts/main.ps1, Action-Test workflow)Settings,Name,WorkingDirectory(plusEventPath/EventJsonfor test overrides)Version,Prerelease,FullVersion,ReleaseType,CreateReleasePublish-PSModule/src/init.ps1(PSSemVer install, GitHub Releases query, PSGallery query, PR-label parsing, bump selection, prerelease sequencing,DatePrereleaseFormat,VersionPrefix)Related PRs:
Version/Prereleaseinputs and stamps them into the manifest at build time.