Skip to content

Commit 87cf094

Browse files
Merge version outputs into Settings object; update README to be declarative
1 parent df0f1c4 commit 87cf094

4 files changed

Lines changed: 44 additions & 84 deletions

File tree

.github/workflows/Build-Module.yml

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,6 @@ on:
1212
description: Name of the artifact to upload.
1313
required: false
1414
default: module
15-
ModuleVersion:
16-
type: string
17-
description: The Major.Minor.Patch version to stamp into the built manifest. Empty falls back to '999.0.0'.
18-
required: false
19-
default: ''
20-
ModulePrerelease:
21-
type: string
22-
description: Optional prerelease tag to stamp into the built manifest.
23-
required: false
24-
default: ''
2515

2616
permissions:
2717
contents: read # to checkout the repository
@@ -43,7 +33,7 @@ jobs:
4333
uses: PSModule/Build-PSModule@v4.1
4434
with:
4535
Name: ${{ fromJson(inputs.Settings).Name }}
46-
Version: ${{ inputs.ModuleVersion != '' && inputs.ModuleVersion || '0.0.0' }}
47-
Prerelease: ${{ inputs.ModulePrerelease }}
36+
Version: ${{ fromJson(inputs.Settings).Module.Version != '' && fromJson(inputs.Settings).Module.Version || '0.0.0' }}
37+
Prerelease: ${{ fromJson(inputs.Settings).Module.Prerelease }}
4838
ArtifactName: ${{ inputs.ArtifactName }}
4939
WorkingDirectory: ${{ fromJson(inputs.Settings).WorkingDirectory }}

.github/workflows/Plan.yml

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ name: Plan
22

33
# The Plan job is the single decision point for the workflow.
44
# It runs two steps:
5-
# 1. Get-PSModuleSettings - loads and resolves configuration
6-
# 2. Resolve-PSModuleVersion - calculates the next version from settings + PR labels
7-
# All downstream jobs consume the Settings JSON and the resolved version outputs from this job.
5+
# 1. Get-PSModuleSettings - loads and resolves configuration
6+
# 2. Resolve-PSModuleVersion - calculates the next version from settings + PR labels
7+
# The resolved version is merged into the Settings object (Settings.Module.*) by the Enrich-Settings step.
8+
# All downstream jobs receive one self-contained Settings JSON with no separate version outputs.
89

910
on:
1011
workflow_call:
@@ -51,23 +52,8 @@ on:
5152
5253
outputs:
5354
Settings:
54-
description: The complete settings object including test suites.
55+
description: The complete settings object including test suites and resolved module version.
5556
value: ${{ jobs.Plan.outputs.Settings }}
56-
ModuleVersion:
57-
description: The Major.Minor.Patch part of the next version.
58-
value: ${{ jobs.Plan.outputs.ModuleVersion }}
59-
ModulePrerelease:
60-
description: The prerelease tag, empty string when not a prerelease.
61-
value: ${{ jobs.Plan.outputs.ModulePrerelease }}
62-
ModuleFullVersion:
63-
description: The full version string including prefix and prerelease tag (for example v1.4.0).
64-
value: ${{ jobs.Plan.outputs.ModuleFullVersion }}
65-
ReleaseType:
66-
description: The release type - Release, Prerelease, or None.
67-
value: ${{ jobs.Plan.outputs.ReleaseType }}
68-
CreateRelease:
69-
description: 'true when a release/prerelease should actually be created.'
70-
value: ${{ jobs.Plan.outputs.CreateRelease }}
7157

7258
permissions:
7359
contents: read # to checkout the repo
@@ -78,12 +64,7 @@ jobs:
7864
name: Plan
7965
runs-on: ubuntu-latest
8066
outputs:
81-
Settings: ${{ steps.Get-Settings.outputs.Settings }}
82-
ModuleVersion: ${{ steps.Resolve-Version.outputs.Version }}
83-
ModulePrerelease: ${{ steps.Resolve-Version.outputs.Prerelease }}
84-
ModuleFullVersion: ${{ steps.Resolve-Version.outputs.FullVersion }}
85-
ReleaseType: ${{ steps.Resolve-Version.outputs.ReleaseType }}
86-
CreateRelease: ${{ steps.Resolve-Version.outputs.CreateRelease }}
67+
Settings: ${{ steps.Enrich-Settings.outputs.Settings }}
8768
steps:
8869
- name: Checkout Code
8970
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -117,3 +98,27 @@ jobs:
11798
Verbose: ${{ inputs.Verbose }}
11899
Version: ${{ inputs.Version }}
119100
WorkingDirectory: ${{ inputs.WorkingDirectory }}
101+
102+
- name: Enrich-Settings
103+
# Merge the resolved version into the Settings object so all downstream jobs
104+
# receive a single, self-contained Settings JSON with no separate version outputs.
105+
id: Enrich-Settings
106+
shell: pwsh
107+
env:
108+
SETTINGS: ${{ steps.Get-Settings.outputs.Settings }}
109+
VERSION: ${{ steps.Resolve-Version.outputs.Version }}
110+
PRERELEASE: ${{ steps.Resolve-Version.outputs.Prerelease }}
111+
FULL_VERSION: ${{ steps.Resolve-Version.outputs.FullVersion }}
112+
RELEASE_TYPE: ${{ steps.Resolve-Version.outputs.ReleaseType }}
113+
CREATE_RELEASE: ${{ steps.Resolve-Version.outputs.CreateRelease }}
114+
run: |
115+
$settings = $env:SETTINGS | ConvertFrom-Json
116+
$settings | Add-Member -MemberType NoteProperty -Name Module -Value ([pscustomobject]@{
117+
Version = $env:VERSION
118+
Prerelease = $env:PRERELEASE
119+
FullVersion = $env:FULL_VERSION
120+
ReleaseType = if ([string]::IsNullOrEmpty($env:RELEASE_TYPE)) { 'None' } else { $env:RELEASE_TYPE }
121+
CreateRelease = $env:CREATE_RELEASE -eq 'true'
122+
})
123+
$enriched = $settings | ConvertTo-Json -Depth 10 -Compress
124+
"Settings=$enriched" >> $env:GITHUB_OUTPUT

.github/workflows/workflow.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,6 @@ jobs:
118118
- Plan
119119
with:
120120
Settings: ${{ needs.Plan.outputs.Settings }}
121-
ModuleVersion: ${{ needs.Plan.outputs.ModuleVersion }}
122-
ModulePrerelease: ${{ needs.Plan.outputs.ModulePrerelease }}
123121

124122
# Runs on:
125123
# - ✅ Open/Updated PR - Tests source code changes

README.md

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ Depending on the labels in the pull requests, the [workflow will result in diffe
4545
- [Workflow overview](#workflow-overview)
4646
- [Plan](#plan)
4747
- [Lint-Repository](#lint-repository)
48-
- [Plan job](#plan-job)
4948
- [Build module](#build-module)
5049
- [Test source code](#test-source-code)
5150
- [Lint source code](#lint-source-code)
@@ -113,65 +112,33 @@ Depending on the labels in the pull requests, the [workflow will result in diffe
113112
The Plan job is the single decision point of the workflow. It runs two steps in sequence:
114113

115114
1. **Get-PSModuleSettings** — loads the settings file (`.github/PSModule.yml`) and emits a fully resolved `Settings` JSON object that every downstream job consumes.
116-
2. **Resolve-PSModuleVersion** — calculates the next module version from the resolved settings and the labels on the current pull request. Emits `ModuleVersion`, `ModulePrerelease`, `ModuleFullVersion`, `ReleaseType`, and `CreateRelease` as job outputs.
115+
2. **Resolve-PSModuleVersion** — calculates the next module version from the resolved settings and the labels on the current pull request.
117116

118-
The resolved version is passed into `Build-Module` so the manifest is stamped with the final version **before** the test stages run. The same artifact is then published unchanged by `Publish-Module`, which also uploads the zipped module as a GitHub Release asset. The bytes that are tested are the bytes that ship to the PowerShell Gallery and to GitHub Releases.
117+
After both steps complete, the resolved version is merged into `Settings` under a `Module` key:
119118

120-
#### How version resolution works
121-
122-
The [Resolve-PSModuleVersion](https://github.com/PSModule/Resolve-PSModuleVersion) step reads configuration from `Settings.Publish.Module`:
123-
124-
| Key | Description |
119+
| `Settings.Module` field | Description |
125120
| --- | ----------- |
126-
| `ReleaseType` | `Release`, `Prerelease`, or `None`. |
127-
| `AutoPatching` | When `true`, a patch bump is applied even without a label. |
128-
| `IncrementalPrerelease` | When `true`, an incrementing counter is appended to prerelease tags. |
129-
| `DatePrereleaseFormat` | Optional .NET DateTime format string for date-based prerelease suffixes. |
130-
| `VersionPrefix` | Tag prefix (typically `v`). |
131-
| `MajorLabels`, `MinorLabels`, `PatchLabels` | Comma-separated PR labels that trigger the corresponding bump. |
132-
| `IgnoreLabels` | Comma-separated PR labels that suppress version creation. |
133-
134-
Resolution algorithm:
135-
136-
1. Loads the `pull_request` event payload and collects PR labels.
137-
2. Validates `ReleaseType`; applies `IgnoreLabels` override (suppresses release if matched).
138-
3. Picks the bump type: `MajorLabels` > `MinorLabels` > (`PatchLabels` or `AutoPatching`).
139-
4. Reads the latest version from GitHub Releases (`gh release list`) and the PowerShell Gallery (`Find-PSResource`),
140-
takes the higher of the two as the baseline.
141-
5. Bumps the baseline (major, minor, or patch).
142-
6. For prereleases, appends the sanitized branch name, optionally a `DatePrereleaseFormat` timestamp, and an
143-
incremental counter calculated from existing prereleases on the same baseline + branch.
144-
7. Emits outputs:
145-
146-
| Output | Description |
147-
| --- | --- |
148121
| `Version` | `Major.Minor.Patch` portion (for example `1.4.0`). |
149122
| `Prerelease` | Prerelease tag, empty when not a prerelease. |
150123
| `FullVersion` | Full string including prefix and prerelease (for example `v1.4.0-mybranch001`). |
151-
| `ReleaseType` | `Release`, `Prerelease`, or `None` when no bump label is found. |
152-
| `CreateRelease` | `true` when a release or prerelease should be created. |
124+
| `ReleaseType` | `Release`, `Prerelease`, or `None`. |
125+
| `CreateRelease` | `true` when a release or prerelease will be created. |
153126

154-
When `ReleaseType` is `None`, when an `IgnoreLabels` label is present, or when no version bump label is found
155-
(and `AutoPatching` is disabled), `CreateRelease` is `false` and the version outputs are empty strings.
127+
All downstream jobs receive this single enriched `Settings` object — there are no separate version outputs.
128+
The version decided here is the version that ships. `Build-Module` stamps it into the manifest before any test runs,
129+
and `Publish-Module` publishes the artifact unchanged.
156130

157131
### Lint-Repository
158132

159133
[workflow](./.github/workflows/Lint-Repository.yml)
160134

161-
### Plan job
162-
163-
[workflow](#plan)
164-
165-
- Reads the settings file `.github/PSModule.yml` in the module repository to configure the workflow.
166-
- Gathers context for the process from GitHub and the repo files, configuring what tests to run, if and what kind of release to create, and whether
167-
to setup testing infrastructure and what operating systems to run the tests on.
168-
- Calculates the next module version from PR labels and existing releases, then publishes it as job outputs so Build-Module can stamp the manifest before the artifact is tested.
169-
170135
### Build module
171136

172137
[workflow](./.github/workflows/Build-Module.yml)
173138

139+
- Receives the resolved version from `Settings.Module` and stamps it into the module manifest before the artifact is uploaded.
174140
- Compiles the module source code into a PowerShell module.
141+
- Produces the artifact that flows unchanged through test and publish stages.
175142

176143
### Test source code
177144

@@ -367,8 +334,8 @@ The [PSModule - Module tests](./scripts/tests/Module/PSModule/PSModule.Tests.ps1
367334

368335
[workflow](./.github/workflows/Publish-Module.yml)
369336

370-
- Publishes the module to the PowerShell Gallery.
371-
- Creates a release on the GitHub repository.
337+
- Publishes the artifact to the PowerShell Gallery exactly as built — no version mutation.
338+
- Creates a GitHub Release using the version already stamped in the manifest.
372339
- Attaches the built module as a `.zip` asset on the GitHub Release so consumers can download the exact bytes that were tested and pushed to the PowerShell Gallery.
373340
- **Abandoned PR cleanup**: When a PR is closed without merging (abandoned), the workflow automatically cleans up any
374341
prerelease versions and tags that were created for that PR. This ensures that abandoned work doesn't leave orphaned

0 commit comments

Comments
 (0)