Repository navigation
Module releases use configurable defaults and owned labels - #524
Marius Storhaug (MariusStorhaug) wants to merge 26 commits into
Conversation
Super-linter summary
All files and directories linted successfully For more information, see the GitHub Actions workflow run Powered by Super-linter |
There was a problem hiding this comment.
Pull request overview
This PR updates Process-PSModule’s default release-intent label contract to use an owned release: namespace (and documents that contract), so downstream release/version decisions default to repository-owned labels instead of potentially colliding dependency metadata.
Changes:
- Switch default publish/version label mappings to
release:major|minor|patch|pre-release|skip(while preserving consumer overrides via.github/PSModule.yml). - Centralize publish-default resolution in
Resolve-PSModulePublishSetting, and publish the same defaults in the settings JSON schema. - Update docs and Pester coverage to reflect and validate the new canonical defaults and override behavior.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| docs/content/specification/spec.md | Updates the FR5 contract and Gherkin scenarios to use release:* default labels. |
| docs/content/specification/principles-and-practices.md | Updates guidance for prerelease flows using the configured prerelease label (default release:pre-release). |
| docs/content/specification/design.md | Aligns design text with the new canonical default label set and override location. |
| docs/content/reference/settings.md | Updates documented settings defaults to the release:* namespace and adds prerelease defaults. |
| docs/content/reference/scenario-matrix.md | Updates prerelease requirements text to reference the configured prerelease label and resolved bump. |
| docs/content/reference/repository-standard.md | Updates repository expectations to the new default label namespace and override guidance. |
| docs/content/reference/powershell-module-standard.md | Updates label tables/examples and prerelease behavior documentation to release:* defaults. |
| docs/content/guides/versioning-and-releases.md | Updates the versioning guide to the new label namespace and clarifies conflict-handling behavior. |
| docs/content/get-started/your-first-release.md | Updates “first release” walkthrough tables/text to the new default labels and conflict semantics. |
| .github/workflows/workflow.yml | Adjusts workflow commentary to describe prerelease conditions in terms of intent + resolved bump. |
| .github/actions/Resolve-PSModuleVersion/tests/Resolve-PSModuleVersion.Helpers.Tests.ps1 | Updates version-resolution tests to use release:* defaults and adds coverage for canonical/overridden mappings. |
| .github/actions/Get-PSModuleSettings/tests/Get-PSModuleSettings.Helpers.Tests.ps1 | Adds tests asserting canonical defaults, consumer override preservation, and schema defaults parity. |
| .github/actions/Get-PSModuleSettings/src/Settings.schema.json | Publishes schema defaults for AutoPatching and the label mapping settings. |
| .github/actions/Get-PSModuleSettings/src/main.ps1 | Uses the new publish-settings resolver when constructing normalized settings output. |
| .github/actions/Get-PSModuleSettings/src/Get-PSModuleSettings.Helpers.psm1 | Introduces Resolve-PSModulePublishSetting to own and centralize canonical defaults. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Release guidance now defines one owned `release:` label set: `release:patch`, `release:minor`, `release:major`, `release:pre-release`, and `release:skip`. Release automation ignores bare and unrelated labels, so only explicit release decisions affect published versions. ## Changed: One release label contract Release Management, Automation Labels, PR Format, Natural Language examples, and the VS Code Extension Framework now use the same namespaced values. Prereleases use `release:pre-release` with one bump label, while non-releasing changes use `release:skip` alone. ## Changed: Ad hoc releases are optional A labeled pull request merge is the required release path. Implementations may add `workflow_dispatch` only when they need an explicit ad hoc mechanism; it must use the same release controls and require its decision and release-note context as inputs. Empty pull requests and direct pushes are not release workarounds. --- <details> <summary>Technical details</summary> - Replaced `release:none` and the unnamespaced `Prerelease` label. - Defined valid and invalid combinations for the five owned release labels. - Made `workflow_dispatch` an optional implementation extension rather than a mandatory release interface. - Preserved the mainline removal of dependency-tool label guidance while resolving the branch update. | Changed surface | Standards checked | Framework docs checked | Result | | --- | --- | --- | --- | | `src/docs/Capabilities/release-management/**` | Natural Language, Markdown | Release Management | Aligned | | Release-label references under `src/docs/**` | Natural Language, Markdown | Automation Labels, PR Format, VS Code Extension Framework | Aligned | </details> <details> <summary>Relevant issues (or links)</summary> ### Related work - References PSModule/Release-GHRepository#109 - References PSModule/Process-PSModule#524 </details> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
A workflow_dispatch on the default branch is the documented recovery route for a failed or cancelled release run. Pull request association was gated on $isPush, so a dispatch resolved no pull request, saw no version label, and silently applied the AutoPatching patch fallback. Widen the gate to cover a manual dispatch on the default branch, so the same association and selection path runs for the same merge commit. Also fail loudly when a merged default-branch pull request is associated with the commit but does not match it, instead of falling back to a patch bump. A wrong version published to the PowerShell Gallery cannot be reclaimed. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Extract the gate, selection, and no-pull-request decision from main.ps1 into Resolve-ReleasePullRequest, with the GitHub lookup injected as a script block. The composed logic that produced the wrong version is now covered directly rather than re-implemented in a test. Add Get-DiscardedReleasePullRequest so a merged default-branch pull request that does not match the released commit fails the run instead of silently applying a patch bump. Open pull requests and non-default-branch merges are ignored, so a direct push and a feature-branch push are unaffected. Each new test was verified to fail against the specific defect it guards. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
| $shouldPublish = ($createRelease -or $createPrerelease) -and $Configuration.Skip -ne $true | ||
| if ($Configuration.Skip -eq $true) { | ||
| $createRelease = $false | ||
| } |
There was a problem hiding this comment.
Confirmed. A new behavior test with Skip = true and ReleaseType = Prerelease fails because CreatePrerelease remains true while ShouldPublish is false. The fix must also prevent the final non-publishing-preview branch from re-enabling creation, while retaining the configured local bump. I preserved the failing test and transferred it under the coordinated resolver ownership; no shared implementation has been changed. This thread and the draft/readiness blocker remain open.
There was a problem hiding this comment.
This fix stays separately scoped to #524; it is not part of #547/#513. I retain its diagnosis/tests/record, while overlapping resolver/publisher/caller writes wait for the publication-safety contract to freeze or the file to be handed back.
The expanded tests now reproduce both failures in Release, Prerelease, and None modes: three creation-flag assertions fail, and three composed version-resolution tests observe a prerelease-counter call despite repository Skip. A positive non-publishing preview still resolves its counter correctly. Targeted run: 91 passed, 6 expected failures. The root cause includes the final unconditional non-publishing-preview branch, so clearing flags only at initialization would be incomplete. No implementation or fix is pushed, and this thread remains open.


Consumers selecting the next compatible major replace
Publish.Module.AutoPatchingwithDefaultBumpand adopt the owned release-label defaults or preserve intentional custom mappings. An explicit configured bump label overrides the effective default; a valid default is sufficient without a bump label. This producer candidate is unmerged and remains blocked by a late module-Skip/prerelease decision finding and the shared publication-safety prerequisites.Breaking: Release defaults are explicit and caller-controlled through settings
Publish.Module.AutoPatchingis removed and rejected, including whenDefaultBumpis also present.Publish.Module.DefaultBumpaccepts exactlypatch,minor, ormajor; omission inherits the shared patch default. It applies to normal and direct default-branch releases. Null, empty, invalid, or unknown publication settings fail instead of silently falling back or being masked by a label.Default mappings are
release:major,release:minor,release:patch,release:prerelease, andrelease:skip;prereleaseis one word. All five settings remain supported and consumer-configurable:MajorLabels,MinorLabels,PatchLabels,PrereleaseLabels, andIgnoreLabels. Intentional mappings, including legacy/custom vocabularies, remain authoritative. Labels outside those configured mappings do not supply release intent.The existing settings-file/
SettingsPathsurface is preserved. No scalar invocation-levelDefaultBumpworkflow input is declared or approved by this PR. Select a settings file with the intended details; do not infer an invocation override interface from the proposed cross-repository contract. The upstream action-specific choice of typedCallerOverridesdoes not extend this framework's approved surface.Adopt the released compatible major as one coordinated change:
AutoPatching: true, remove that key and useDefaultBump: patch, another deliberately chosen supported level, or the omitted-key patch default. Do not supply both keys.AutoPatching: false, remove it and choose the effective default explicitly. There is no boolean equivalent that disables defaults. Use the configured skip label for changes that must not release, orPublish.Module.Skip: trueto disable repository-wide module publication while retaining validation. Do not treat an invalid default as a no-release policy. The repository-Skip/prerelease edge must be corrected before this draft becomes an adoptable release.release:patch,release:minor,release:major,release:prerelease, andrelease:skip. Retain intentional custom mapping settings where applicable. No label deletion, historical relabeling, or fleet migration is required here.unlabeledso removing an override recomputes the effective default and removing prerelease mode stops publication.v8line, movev8across this boundary, or use an unmerged producer branch/SHA as a production dependency. No intermediate installation is required by this change.This repository setting makes minor the effective level when no configured bump label exists. A configured patch or major label overrides it.
Publish.Module.DefaultBumpSourceis derived runtime evidence, not an authorable input.Technical details
The immutable composed candidate is
0fb4234056b3bd4574c58cd4edd6dff2544d70f6. Its separately scoped settings delta is compared with frozen recovery headd06a8775f5e37d14fc9e641ef364cb42ada260b0; comparison main is64ffb1d87f86bd5d487891fdb140b78385a00531. Existing branches and original/user commits are preserved. The default PR target remains main; recovery is the prerequisite integration layer, not a claim that its unmerged changes are delivered.Resolve-PSModulePublishSettingowns effective defaults, all five configurable mappings, unknown-key/removed-key rejection, and shared-versus-settings provenance. The schema rejectsAutoPatchingand unknown publication properties while explicitly allowing derived runtime resolution fields.Get-PublishConfigurationrejects mixed legacy input and retains mappings; the release decision records label/default source rather than inventing patch recovery.Frozen-head baseline evidence: 176 full action tests pass with actual shuffled parallel suite execution locally; the real hosted 176-test suite,
Lint code base, DocsLint, and DocsBuildsucceed at this exact head. Eighteen uncovered contract cases fail before correction and pass afterward; two module-Skip behavior cases and the actual schema unknown-key case are also demonstrated. PowerShell analysis is clean. The Zensical build succeeds. Both documented full-default YAML examples validate against the actual schema after correcting the pre-existingName: nullexample to omit the key; this changes guidance, not Name resolution behavior. Hosted parallel execution is not inferred from the existing discarded configuration probe. These baseline successes do not cover or close the newly reproduced Skip/prerelease creation-flag gap.Normal workflow inputs, settings-file formats,
SettingsPath, cleanup settings, version prefix, and prerelease formatting controls remain supported. No secret, permission, runtime, date strategy, or Discord change is introduced. No external template is edited or declared ready. The default/with-manifest caller fixtures retain their interfaces; later caller/template authoring work is separately coordinated and must provide compatible immutable evidence before release adoption.The old PR record's retained-
AutoPatching,release:pre-release, unconditional direct patch, and historic complete-validation claims were corrected from immutable code evidence. The approved replacement direction is retained. The original issue's obsolete retained-boolean wording must not be read as evidence to revert that decision.Related references
Fixed: Preview, prerelease, and skip events use one validated decision
Open non-publishing PR previews validate the same explicit/default level and conflicts instead of being mistaken for closed-PR cleanup. Removing a bump override while prerelease mode remains uses the effective default; removing prerelease mode stops publication. A valid configured skip label stops new-version resolution. Closed-PR cleanup remains non-publishing and ignores obsolete/conflicting release labels.
Open decision blocker: Repository-wide
Publish.Module.Skipdisables publication-enabled state, but the resolver still leaves or re-enablesCreatePrereleasein Release, Prerelease, and None modes. Review comment 4432039974 is reproduced by preserved uncommitted behavior tests. Both creation flags must remain false, including after the final non-publishing-preview branch, while retaining the configured local bump. This fix remains separately owned by #524, not absorbed into #547/#513. Overlapping resolver/helper/publisher/caller writes wait until the publication-safety contract freezes or its owner explicitly hands back the file. No implementation is changed here; the actual fix and reviewed composition are required before readiness.No extra caller input or per-PR bump label is required for a valid default. Consumers using the preserved caller interface need only the settings/label adoption above and its existing
unlabeledevent subscription after the complete compatible release is available.Technical details
Normalized event state distinguishes closed cleanup from open preview. All five mapping settings, including custom prerelease and ignore mappings, feed the same conflict validation. Actual settings-controller tests check publication-enabled state for module Skip; the late decision edge remains open in thread
PRRT_kwDOKhokxM6yRlG6, root comment4432039974, review5723280955. Source and label precedence remain settings-driven and do not depend on PR author or an unrelated label namespace.The bounded diagnosis is two-part: initialization clears only
CreateRelease, then the finalif (-not $shouldPublish)unconditionally enablesCreatePrerelease. That sendsGet-NextModuleVersioninto prerelease-counter resolution even with repository publication disabled. Clearing both flags early alone would be incomplete. The eventual separate #524 correction must preserve normal non-publishing previews, configured bump/default validation, mappings, label conflicts, and closed cleanup without changing the safety owner's Gallery ownership algorithm or caller contract.The separate pagination allegation is resolved as a verified false positive. Exact CI-supported GitHub module 0.43.1 already follows
RelationLink.next, and PowerShell.Responseenumeration consumes all returned pages. The actual settings controller rejects an already-released commit found in the second response after 100 prereleases, without emitting settings output. A second pagination implementation is not needed.Local test-only additions in two files are preserved, not pushed. The targeted shuffled/parallel run executes 97 cases: 91 pass and six Skip regressions fail as expected. Three cover both creation flags in Release/Prerelease/None modes; three compose the decision into actual version resolution and require zero calls to the owned prerelease-counter boundary. Configured default and explicit-label local bumps remain asserted. The positive normal preview still resolves its counter to
v1.3.0-feature007, and the 101-release pagination control passes. Both changed test files have zero analyzer diagnostics. This is evidence for the retained diagnosis, not a green replacement candidate or a claim that the review fix is delivered.The bounded recovery ancestor is frozen separately; its retry/footer consistency finding remains with the publication-safety owner and unresolved. This PR does not implement the systemic publication-safety contracts in #513 and #547. Their overlapping version-resolver/Gallery-publisher/caller changes remain coordinated under one owner, without taking this separate DefaultBump/Skip fix. A clean current-head review, including summary/suppressed findings, remains a readiness gate.
Related references
Release decisions
release:majorintent for the removed boolean and changed default mappings/direct-release behavior. The current native caller still pins released Release-GHRepository v2.0.3 at750abed0ecab02394554b610dc3aa191e75e3248; that reader ignores the owned major label and can resolve patch. That incorrect production result is rejected as a publication prerequisite, not claimed as a verified major release. A stable released immutable compatible engine and its verified caller/check integration are required.v8is not moved.release:major. This PR stays draft until the Skip/prerelease finding, Default-branch recovery retains release intent and immutable artifacts #531/Resume source-bound Gallery-only publication on retry #513/Validate source-bound ownership before module publication #547, compatible upstream production interfaces, current-head review/checks, and enforced required release-decision validation are satisfied. Current main has no required-status-check rule; documentation does not create enforcement.