Skip to content

Release decisions use owned labels and effective settings - #109

Draft
Marius Storhaug (MariusStorhaug) wants to merge 27 commits into
mainfrom
namespaced-release-labels
Draft

Marius Storhaug (MariusStorhaug) wants to merge 27 commits into
mainfrom
namespaced-release-labels

Conversation

@MariusStorhaug

@MariusStorhaug Marius Storhaug (MariusStorhaug) commented Aug 28, 2026 •

Copy link
Copy Markdown
Member

Repository and workflow maintainers must migrate conventional settings to .github\release.settings.yml and replace legacy release labels and AutoPatching when selecting this release. Owned labels override a validated DefaultBump, whose documented default remains patch; explicit CallerOverrides select invocation-specific settings without GitHub-injected defaults masking repository settings.

The caller migration and old-publisher bootstrap requirements are included below. This is a breaking engine update, not the later push-authoritative publisher delivery, and its draft source is not a production dependency.

Breaking: Owned release controls replace legacy labels and automatic patching

AutoPatching, IgnoreLabels, MajorLabels, MinorLabels, and PatchLabels are removed from the action interface. Repository configuration containing those keys now fails instead of silently losing its intent. DefaultBump accepts exactly lowercase patch, minor, or major; a valid inherited patch default is policy, not recovery from invalid input.

Only the five labels below select release behavior. Bare labels, dependency-version labels, unknown namespaces, noncanonical casing, and the retired release:pre-release spelling do not select a bump. Without an owned bump or skip, the effective default applies. Multiple bump labels, or release:skip combined with another owned release label, fail.

Owned label Effect
release:patch Override the valid effective default with a patch bump.
release:minor Override it with a minor bump.
release:major Override it with a major bump.
release:prerelease Select prerelease mode for an open PR, using its explicit or effective default bump.
release:skip Successfully validate without resolving or publishing a version.

Existing v2 references are unchanged. Apply this release-wide adoption path to callers using v2:

  1. Inspect the release job's actual reader reference and effective legacy label settings before changing them. A reader pinned to v2 does not recognize an owned major label by default. While the breaking migration PR is still processed by that reader, retain its supported legacy major signal and add release:major for the new reader. Under the v2 defaults this is major plus release:major. A skipped transition similarly needs the old NoRelease signal plus release:skip. These are temporary signals on the active migration PR, not a historical relabeling campaign.
  2. Wait for the producer's normal human review and authorized release process to publish the breaking engine update. Then select that release's full immutable source SHA in the caller. Do not use this draft PR head, a draft tag, or an unverified moving major reference as a production dependency. No intermediate installation of every earlier version is required; the old-reader bootstrap and producer publication must precede the caller reference change.
  3. Replace AutoPatching: true with DefaultBump: patch, or omit DefaultBump to inherit patch. Choose minor or major only when that is the intended default. There is no none or date bump. Where AutoPatching: false previously suppressed unlabeled publication, apply release:skip to the affected active PR instead. Remove the four label-list keys and translate their active decisions to the owned set.
  4. Add issues: write alongside the existing release/comment permissions. Subscribe the release workflow to opened, reopened, synchronize, labeled, unlabeled, and closed for its release target, without workflow path filters that bypass decision validation. A privileged pull_request_target writer must check out trusted base code, never an untrusted PR head. Validate candidate code in a separate read-only PR workflow. Queue publication without cancellation; serialize merged releases by target branch while isolating open-PR prereleases by PR number.
  5. The first non-dry run provisions and reconciles the five owned labels. If the migration PR needs a label before that run, provision the needed canonical labels through the repository's authorized setup path. Keep unrelated labels; no bulk deletion or historical label migration is required.
  6. Run the existing action validation read-only with CallerOverrides setting WhatIf: true. Confirm that inherited/default, explicit bump, prerelease, skip, conflicting-label, and invalid-setting cases produce the expected decision and source. Keep UsePRBodyAsReleaseNotes and UsePRTitleAsNotesHeading true to preserve the complete authored title/body record; their existing opt-out settings remain supported in this bounded resolver delivery.
with:
  DefaultBump: patch
  CallerOverrides: |
    WhatIf: true

Stable publication remains PR-state-driven in this delivery. Do not add push/manual stable-publication triggers or relabel historical merged PRs expecting validation-only behavior. Exact pushed-source authority, recovery/manual contexts, publication provenance, and controlled alias advancement are separate work in #108.

Technical details

The consumer-change baseline is the released v2.0.3 source 750abed0ecab02394554b610dc3aa191e75e3248. The development candidate is 03e20b8293dd8dfb41bead3255930a5edbb2e9bb; it is evidence for this change, not an authorized released dependency. The actual publication version, source, version base, and consumer-change baseline are resolved by the release process, not predicted here.

The existing resolver coverage is retained, including all 32 owned-label subsets across all three defaults. The repository suite now has 167 passing cases. Eleven anonymous bootstrap experiments execute the immutable v2.0.3 controller and the candidate with real YAML/SemVer dependencies and write-denying CLI mocks: owned-major-only resolves patch under the old defaults; dual major resolves major under both readers; old skip needs NoRelease, while the new reader honors release:skip. The three filename cases prove that renaming only an old caller's file can discard its major policy; explicit compatible old-reader wiring preserves it. No release, tag, or production file is changed by those experiments.

The repository's own post-merge writer checks out the trusted default branch and uses its local action. This makes the merged owned-label reader available for the producer's breaking decision. A separately pinned framework caller remains on its old reader until an authorized immutable engine release is adopted; the new label alone does not bootstrap that caller.

The integration template baseline inspected is PSModule/Template-Action@634ca503a47a39ca26d72fa59c784da8118ae835. Its Auto-Release workflow still selects the old reader, lacks the new label permission/event contract, and is not a verified unchanged template for this release. A separate template/caller delivery is required; no compatible updated template commit is claimed here. The exact caller changes are specified above rather than left for consumers to infer from that template.

Changed surface Standards checked Framework docs checked Result
Owned labels, defaults and decision helpers PowerShell, Functions, Error Handling, Testing Release Management settings/label contract in MSXOrg/docs#209 Fixed in this PR
Action inputs and trusted/read-only caller workflows GitHub Actions, YAML, Security Native action contract and release-route validation Fixed in this PR; runner pinning remains #105
Required decision enforcement Definition of Ready for Review, release-decision check contract Protected main-branch rule evaluation Exception - #112

The hosted review at 89b7766 identified two cleanup-matching defects and unnecessary version parsing on skip; all three were reproduced with failing tests, fixed in b8767c4, and replied to/resolved. The subsequent user-directed settings-filename revision is verified at 03e20b8: all 167 repository cases, eleven old-reader controls, two unchanged anonymous authentication checks, and exact-head hosted CI pass.

The complete current-head review reports no open issues. Its summary defers end-to-end assessment of authenticated label/release/tag/push operations and GitHub event/checkout semantics; it is not an automated approval or evidence of live publication. No unauthorized publication or gate weakening is performed to manufacture that evidence.

The prior review at b8767c4 reports no open issues, but its complete summary asks for closer assessment of authenticated tag pushes. The default-bootstrap concern was evaluated against the actual GitHub 0.43.1 dependency in CI: account/context initialization calls Git authentication configuration before publication. Two passing anonymous checks exercise that real path with API/vault/writes mocked and prove native Git URL expansion without contacting a remote. The assessment is recorded with immutable dependency sources, not called an automatic approval or used to weaken checkout security.

The PR stays draft because its native delivery issue is blocked by #112; main has no required-status-check rule, and that enforcement was not bypassed.

The scoped issue-convergence sweep checked the release-related open issues. This PR delivers #111. It does not deliver push authority in #108 or #61, the remaining runner work in #105, or governance enforcement in #112; those remain separate.

Related references

Breaking: Release settings use the canonical filename

ConfigurationFile now defaults to .github\release.settings.yml, replacing .github\auto-release.yml. This is an actual reader change, not only a documentation rename. The input name, its custom-path capability, settings keys, scalar/file/typed-override precedence, and the patch default remain unchanged. Module PSModule.yml and its distinct SettingsPath interface are not migrated by this action release.

For consumers using the former conventional file, make the following changes in the same reviewed caller adoption as the compatible release-engine reference:

  1. After an authorized immutable engine release supporting this contract exists, rename .github\auto-release.yml to .github\release.settings.yml and retain its intended valid settings. Apply the removed-key/owned-label migration from the preceding section in that same caller change. Do not rename only the file while an older production reader still relies on its old default; it would miss the configured policy.
  2. Keep the input name ConfigurationFile. If the caller explicitly supplied the old conventional path, remove that input to inherit the new default or change its value to .github\release.settings.yml. Other intentional custom paths remain supported through this input; no second conventional path or legacy alias is added.
  3. If both conventional files exist, reconcile their intended policy into the new file and remove the obsolete file through the reviewed caller change rather than letting the engine guess which policy is intended. Selecting the removed conventional path explicitly is an error too. A deliberately selected existing custom file is read as directed; a missing custom file cannot silently discard an existing legacy conventional file.
  4. Validate the candidate caller with CallerOverrides setting WhatIf: true. Confirm that the new file is reported as read, the expected default/owned bump and its source are visible, and no GitHub write occurs. A legacy-only file or an explicitly selected old conventional path must produce a rename/compatible-reference diagnostic before any GitHub operation.
# Caller before adoption
with:
  ConfigurationFile: .github\auto-release.yml
# Caller after selecting the compatible published engine and renaming the file
with:
  ConfigurationFile: .github\release.settings.yml
  CallerOverrides: |
    WhatIf: true

When no conventional settings file exists, no file creation is required: valid documented defaults and existing caller inputs still apply. A consumer using a valid unrelated custom path has no filename edit beyond selecting the compatible released engine. Reading release records does not require installing every intervening version; this filename and reader must be adopted together, and no draft source is a production dependency.

The .github\release.config.yml name appears in earlier canonical guidance, but the released v2.0.3 action does not automatically read it. A caller that deliberately selected that name through ConfigurationFile is using custom-path control, not a discovered alias. Inspect and preserve that explicit wiring or change it deliberately with the compatible reader; there is no inferred migration of a runtime loader that this action never had.

Technical details

The filename result shares the released v2.0.3 source baseline and exact candidate identified above. The standalone settings revision is b8767c42b5140ea66e865cbd0142cd2f7c2cbde7 to 03e20b8293dd8dfb41bead3255930a5edbb2e9bb, kept separate from the full released-source comparison. Two ordinary commits separate the tested actual-reader change from its target-state documentation.

Seventeen cases exercise the declared default and env forwarding, default-file loading without an injected ConfigurationFile, valid absence, legacy-only/conflicting files, relative/normalized/absolute old selections, deliberate custom control, missing custom with legacy data, scalar/file/CallerOverrides/owned-label precedence, invalid new data and WhatIf no mutation. Sixteen fail against the prior reader before implementation; the existing custom-path case already passes. All 167 repository cases and eleven old-reader bootstrap experiments pass after the change.

The default remains declared only in action.yml. The controller resolves caller paths using PowerShell's provider-aware path resolver and checks the removed conventional path solely to reject it; it never reads it as fallback. No resolver helper export, settings key, input name, module PSModule.yml, or PSMODULE_AUTO_RELEASE_INPUT_* environment namespace changes.

Canonical correspondence is verified against MSXOrg/docs#233 at immutable candidate 734145479ede01a7ccdeb4eb29950d405ed99a09. The Naming standard owns <name>.settings.yml once, preserves documented explicit custom-path control, and requires reader-verified migration. This action declares and tests the corresponding .github\release.settings.yml default without changing its input or schema.

The module-settings exception retains .github/PSModule.yml through SettingsPath and does not require an extra module release-settings file. Those distinct contracts are unchanged here. The canonical amendment is still a draft documentation candidate, not shipped runtime support or a production dependency.

Changed surface Standards checked Framework docs checked Result
ConfigurationFile default, controller migration boundary and caller fixtures PowerShell, Error Handling, Testing, YAML Actual action contract and user-directed canonical settings convention Fixed in this PR
README defaults and custom-path example Natural Language, Markdown, Documentation Model Release settings usage; exact old-to-new adoption remains in this PR record Fixed in this PR

The updated interface/head is shared with the Project coordinator and linked in the existing PSModule/Release-GHRepository#108 handoff. No distinct publication owner or working-copy incorporation is verified. No push-authority rewrite, production caller pin, module-settings migration, package/tag/release publication, or live governance change occurs here. The native #112 prerequisite and maintenance-only merge_pr=false limit remain.

Related references

New: Explicit caller overrides preserve repository defaults and invocation intent

CallerOverrides is a string input containing a YAML or JSON mapping of explicit release-setting overrides. It is the supported invocation-over-repository channel. GitHub injects scalar action defaults even when a caller omits them, so individual scalar inputs retain their existing lower-than-file precedence instead of pretending to reveal whether the user explicitly supplied a default value.

Effective settings resolve as shared defaults declared in action.yml, scalar base inputs, repository settings from .github\release.settings.yml (or an intentional ConfigurationFile custom path), then explicit CallerOverrides. An omitted {} mapping inherits repository settings. An owned bump label still overrides a valid effective DefaultBump. The action reports the effective setting/bump source.

For a caller that must select minor while its repository normally selects major, use a block scalar or a JSON string, not a YAML object directly under with:. Existing callers that need no invocation override can omit this input.

with:
  CallerOverrides: |
    DefaultBump: minor
    AutoCleanup: false
    VersionPrefix: ''
with:
  CallerOverrides: '{"DefaultBump":"minor","AutoCleanup":false,"VersionPrefix":""}'

Explicit false and empty supported text values are preserved. Booleans accept YAML Boolean values or case-insensitive strings containing exactly true or false; numeric and arbitrary truthy values are rejected. Only VersionPrefix and the existing DatePrereleaseFormat accept empty strings. Null, unknown, removed, or malformed values fail in every supplied scope even when a narrower scope or an owned label supplies a valid value. Remove the invalid lower-priority value rather than trying to mask it with an override. DatePrereleaseFormat remains a prerelease-suffix formatter, not date versioning.

The file and override mapping accept the runtime release-setting names, excluding CallerOverrides and ConfigurationFile themselves. Debug, Verbose, Version, Prerelease, and WorkingDirectory remain separate dependency/runtime inputs. In particular, Prerelease selects a prerelease GitHub module dependency; repository prerelease mode uses the owned label.

Technical details

This result uses the same released v2.0.3/source baseline and development candidate identified in the breaking section. The typed override channel was selected explicitly for this delivery; it introduces no new orchestration framework or second bump algorithm.

The settings resolver validates each layer before applying it and returns the effective DefaultBump source. The decision resolver retains Bump, Prerelease, Skip, and DefaultBumpApplied, adding BumpSource. Real-controller tests verify YAML and JSON overrides, inherited repository values despite injected scalar defaults, false/empty values, explicit-label precedence, source reporting, unmasked invalid inputs, and forced read-only validation over a valid WhatIf: false file setting. All write commands are denied in these tests.

Changed surface Standards checked Framework docs checked Result
CallerOverrides, configuration parsing and decision provenance PowerShell, Functions, Error Handling, GitHub Actions Documented settings/caller precedence in MSXOrg/docs#209 Fixed in this PR
Input reference and usage guidance Natural Language, Markdown, documentation model Native action input contract Fixed in this PR; release-specific adoption remains in this PR record

No consumer edit is needed for the unchanged supported scalar settings/defaults when no invocation-specific override is required. A template using the old reader cannot yet consume this new input; its required release-reference/permission/event migration is covered in the breaking section.

Related references

Fixed: Prerelease publication and cleanup use validated source context

Open-PR prereleases target the exact validated 40-character head commit, not a potentially missing or colliding base-repository branch name. The normalized branch name still names the prerelease. A branch without an ASCII prerelease identifier fails only when prerelease mode requires it; valid stable/skipped contexts do not fail because an unused prerelease name is empty.

Cleanup locates the first numeric version core and compares its following prerelease identifier case-sensitively. Only the exact escaped identifier ending the tag or followed by a dot is eligible; later embedded hyphens and later version-like segments cannot select a candidate. Stable releases, invalid/non-version cores, longer identifiers, and regular-expression lookalikes are excluded. Empty and hyphenated version prefixes retain cleanup support. Closed skipped PRs still receive configured cleanup without parsing the latest version, even when that unrelated latest tag is malformed; stable GitHub Releases are never cleanup candidates.

Publication runs queue without cancellation. Merged-PR publication shares a target-branch concurrency key; open-PR prerelease runs remain isolated by PR number. This fixes the race introduced by making every publication PR-specific without bundling the later push-authority publisher.

Select this authorized release to obtain these fixes; no naming, note, or cleanup setting changes are required beyond the caller migration above. WhatIf previews operations without executing label, release, tag, or comment writes.

Technical details

The baseline and candidate are the same as the preceding results. Cases cover fork-style/colliding head refs, missing/mutable/malformed SHAs, exact cleanup boundaries, numeric stable versions, regex escaping, open/closed prerelease gating, a Git-validated non-ASCII branch in a skipped context, and the actual publishing workflow's no-cancellation/branch-serialization settings. PowerShell analysis, actionlint, Markdown lint, and the repository tests pass locally; final hosted CI/review is evaluated separately.

Branch-derived prerelease naming is intentionally retained. PR-unique prerelease identity, broader retention/recovery, the full durable/RC lifecycle, and exact stable-source/publication-envelope enforcement are not claimed by this change.

Changed surface Standards checked Framework docs checked Result
Prerelease context and cleanup helpers/controller PowerShell, Error Handling, Testing Existing native prerelease contract Fixed in this PR
Publishing concurrency and trusted trigger GitHub Actions, least privilege, serialized mutation Native repository publication route Fixed in this PR; remaining runner pinning is #105
Related references
Release decisions
  • Release: Yes - this repository's main route delivers a versioned GitHub Action, and supported release-label/input contracts change.
  • Version bump: Major - the applied release:major overrides the valid patch default because legacy controls are removed and invalid settings now fail.
  • Mode: Stable - the default-branch repository release route is the stable authority; this PR does not request prerelease mode.
  • Labels: release:major

The release process resolves the final version, tag, immutable published source, version-computation base, and consumer-change baseline at publication. No final numeric version or production dependency is assigned to this draft candidate.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a strict, “fail-closed” release-decision model based on a canonical, action-owned release: label set, removing legacy/bare label influence and eliminating default/automatic patching behavior.

Changes:

  • Adds a PowerShell helper module to define canonical release labels and to resolve/validate release decisions from PR labels.
  • Updates the main action logic to (a) provision canonical labels each run and (b) drive release/prerelease/skip decisions exclusively via the resolver.
  • Updates documentation, action inputs, and workflows to reflect the new owned-label contract and required events/permissions; adds unit tests for the resolver.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/Release-GHRepository.Helpers.Tests.ps1 Adds Pester coverage for canonical label definitions and release-decision resolution/rejection rules.
src/Release-GHRepository.Helpers.psm1 Introduces canonical label definitions and the strict Resolve-ReleaseDecision validator.
src/main.ps1 Provisions canonical labels and replaces legacy label/auto-patching logic with the resolver output.
README.md Documents the owned-label contract, workflow requirements, and v2→v3 migration steps.
action.yml Removes legacy label/auto-patching inputs and clarifies Prerelease input semantics.
.github/workflows/Release.yml Ensures label transitions are evaluated (unlabeled) and grants issues: write for label provisioning.
.github/workflows/Action-Test.yml Adds Pester unit tests and expands PR event types to include unlabeled.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/Action-Test.yml Resolved
Comment thread .github/workflows/Release.yml Resolved
Comment thread src/main.ps1 Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/main.ps1:154

  • $createPrerelease can become true for merged/closed pull requests when the PR targets a non-default branch (because $closedPullRequest only covers closed-but-not-merged). That would create prereleases from closed PRs, conflicting with the intended “open pull request prerelease” behavior.
$createPrerelease = $releaseDecision.Prerelease -and -not $createRelease -and -not $closedPullRequest

Comment thread .github/workflows/Release.yml Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

.github/workflows/Release.yml:19

  • pull_request_target sets github.ref to the base/default branch (e.g. refs/heads/main), so using ${{ github.workflow }}-${{ github.ref }} collapses all PR runs into the same concurrency group. With cancel-in-progress: true, activity on one PR can cancel an in-progress run for a different PR, which can interrupt release/prerelease creation or cleanup. Use a PR-scoped key (e.g. PR number) to isolate runs per PR (matching the README guidance).
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Marius Storhaug (MariusStorhaug) added a commit to MSXOrg/docs that referenced this pull request Aug 29, 2026
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>
@MariusStorhaug
Marius Storhaug (MariusStorhaug) marked this pull request as ready for review August 29, 2026 11:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The prerelease-cleanup selection in src/main.ps1 can match and delete non-prerelease (stable) releases because it uses a broad substring tag filter without restricting to isPrerelease.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread src/main.ps1 Resolved
@MariusStorhaug Marius Storhaug (MariusStorhaug) changed the title 🌟 [Major]: Release decisions use owned labels Release decisions use owned labels and effective settings Oct 31, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Approval is blocked by two critical prerelease-cleanup matching bugs that can delete the wrong tags and a moderate skip-path issue that can fail validation unnecessarily.

3 open issues
1 resolved since last review

Review effort: Lite

Comment thread src/Release-GHRepository.Helpers.psm1 Resolved
Comment thread src/Release-GHRepository.Helpers.psm1 Resolved
Comment thread src/main.ps1 Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Human assessment is needed because critical hidden findings indicate the stable-release workflow may fail during authenticated tag pushes despite successfully creating the GitHub Release.

No open issues 🎉

3 resolved since last review

Review effort: Lite

@MariusStorhaug

Copy link
Copy Markdown
Member Author

Assessed the latest review summary's authenticated-tag-push concern against the actual default bootstrap. The read-only checkout does not leave Git unauthenticated in this path: GitHub-Script v1.9.0 calls Connect-GitHub, and GitHub 0.43.1 initializes the workflow installation context, then configures authenticated Git URL rewrites before the script runs.

The actual final-head action job reports GitHub 0.43.1. Two anonymous bootstrap checks pass: they exercise the real context/Git-config functions with API, vault, CLI-login and Git-write boundaries mocked, then use real git ls-remote --get-url to prove authenticated URL expansion without contacting a remote. No real credential, global configuration, release, tag, permission or policy is changed by those checks. The active immutable-tag rule protects three-component tags; it does not target the moving major/minor aliases.

No code change is needed to enable persisted checkout credentials merely to silence this summary concern. The three reported resolver/cleanup/skip issues are fixed and resolved, and all final-head CI is green. The summary assessment is documented rather than called an automatic approval; the PR remains draft with its real decision-enforcement prerequisite still open.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Automated review should defer because the privileged workflow’s authenticated label, release, tag, and push operations plus GitHub event and checkout semantics cannot be validated end to end.

No open issues 🎉

Review effort: Lite

Marius Storhaug (MariusStorhaug) added a commit to MSXOrg/docs that referenced this pull request Nov 2, 2026
Solution-owned settings use the conventional filename
`<name>.settings.yml`. The release solution uses
`.github/release.settings.yml`; module repositories retain
`.github/PSModule.yml` through `SettingsPath`, including module release
settings.

The documentation-content test file and CI documentation-index drift
gate are removed. Functional tooling tests, linting, link validation,
and site builds remain; no module migration or runtime loader is
implemented here.

<!-- ANNOUNCEMENT STOP -->

## Removed: Tests that lock documentation content

`tests/PR-Format.Tests.ps1` is deleted in full at the user's request,
including its PR-format, filename, naming, and repository-policy
assertions. No replacement tests of checked-in documentation or workflow
content are added. The Naming standard no longer claims test coverage
for its prose.

The follow-up audit covers all six remaining suites and both workflows.
The remaining suites exercise scripts on temporary fixtures, PowerShell
engine behavior, and plugin metadata/schema validity. They do not lock
the actual documentation's wording or assert the actual workflows'
contents. The user explicitly chose to retain these functional tool
tests, together with linting, link validation, and site builds.

<details>
<summary>Technical details</summary>

The entire 329-line documentation suite is absent, including all 39
assertions it contained. Historical audit comments and earlier test
totals describe preceding iterations, not tests present in this
candidate. No replacement prose or workflow-content tests were
introduced.

The complete scoped comparison is accepted main
`aa9b5cecc69f4cbe6aa04a5dd70ff9cdadeeac3d` to candidate
`8daf026a14036dee04786d371883e8871b5ec2f4`. The [latest bounded
change](3d7c58e...8daf026)
removes drift enforcement without changing any test suite or
index-generator logic.

| Changed surface | Standards checked | Framework or domain docs checked
| Result |
| --- | --- | --- | --- |
| `tests/PR-Format.Tests.ps1` (deleted) | User-directed removal and test
discovery | Existing Pester suite discovery | Aligned |
| Naming enforcement statement | Naming, Natural Language, Markdown |
None (no framework-specific docs) | Aligned |

All 64 tests in the six retained functional suites pass on the current
head, verified from the completed CI job. The six index-tool fixture
cases also pass locally; these exercise optional diagnostics,
regeneration, and line endings on temporary files, not drift in this
repository's actual docs. No suite is rewritten to inspect the
checked-in documentation or workflows.

The [fresh exact-head
review](#233 (review))
approves `8daf026a14036dee04786d371883e8871b5ec2f4` with zero new inline
comments. All five required checks pass:
[Lint](https://github.com/MSXOrg/docs/actions/runs/41497449037/job/125456000472),
[Build](https://github.com/MSXOrg/docs/actions/runs/41497449037/job/125456000462),
[Links](https://github.com/MSXOrg/docs/actions/runs/41497449037/job/125456000312),
[Test](https://github.com/MSXOrg/docs/actions/runs/41497449037/job/125455999512),
and [Cross-repository
links](https://github.com/MSXOrg/docs/actions/runs/41497448823/job/125455993357).
The earlier consistency thread remains resolved. Publishing is
intentionally skipped for this PR.

</details>

<details>
<summary>Related references</summary>

- Resolves #232

</details>

## New: Solution-owned settings filenames identify their owner

Use the owning solution's name for its conventional settings filename.
The Naming standard defines this once; repository, YAML, and release
guidance link to it. The rule does not rename tool-mandated manifests,
lockfiles, workflow filenames, or arbitrary YAML files, and it does not
impose one directory on every solution. Supported explicit custom paths
remain governed by each reader's existing input contract.

Module repositories keep `.github/PSModule.yml` through `SettingsPath`,
including module release settings. The PSModule initiative records this
supported exception and links to the framework's actual input and
settings references. No module filename migration, second release
settings file, or caller-input change is required here.

The VS Code framework design retains `.github/vscode-extension.yml` as
an explicit supported naming exception. Its settings keys and interface
are unchanged; a filename change requires a verified reader and separate
template/caller migration.

<details>
<summary>Technical details</summary>

| Changed surface | Standards checked | Framework or domain docs checked
| Result |
| --- | --- | --- | --- |
| `src/docs/Coding-Standards/Naming.md` | Naming, Natural Language,
Markdown, standard template | None (no framework-specific docs) |
Aligned |
| `src/docs/Coding-Standards/YAML.md` | YAML, Naming, Markdown | None
(no framework-specific docs) | Aligned |
| `src/docs/Ways-of-Working/Repository-Standard.md` | Repository
Standard, Naming, Markdown | Repository Governance required-files model
| Aligned |
| `src/docs/Initiatives/PSModule.md` | Documentation Model, Natural
Language, Markdown | Process-PSModule workflow inputs and settings |
Aligned |

`Naming.md#solution-settings-files` owns the rule;
`PSModule.md#module-settings` and the VS Code configuration surface own
the supported exceptions. Related guidance links to those owners rather
than defining another rule. The directly related obsolete framework
overview link is corrected to its actual canonical site route.

The module default was verified from Process-PSModule source
`105e4dcefe1946782066aa50a5c7d3658319895a` and the [published
workflow-input
reference](https://psmodule.io/Process-PSModule/reference/workflow-inputs/).
The [settings
reference](https://psmodule.io/Process-PSModule/reference/settings/)
owns module keys and defaults. Neither the workflow, its input, schema,
nor enriched runtime settings object changes here.

The earlier VS Code consistency finding remains addressed by its
owning-guide exception, independently of the deleted assertion. The
scoped issue-convergence search finds no additional complete ask
satisfied by this naming slice; broader default-bump/keyed-route and
lifecycle work stays separate.

</details>

## Changed: Release settings use the release solution's canonical
filename

The optional release-solution file is `.github/release.settings.yml`,
replacing the documented `release.config.yml` convention. Its `.github`
location, settings keys, schema, defaults, precedence, omission
behavior, applicability, and required decision validation are unchanged.
All 17 original current-guidance substitutions remain. This repository
has no settings file or runtime loader to rename.

The former `.github/auto-release.yml` is migration evidence for the
separately owned Release-GHRepository reader change, not a current
alternative convention. `ConfigurationFile` remains the public input,
distinct from its conventional default filename. This documentation PR
does not deliver or release that reader. Consumers verify their producer
revision and its migration record before adopting a changed default;
module release settings remain under the supported `PSModule.yml`
interface.

<details>
<summary>Technical details</summary>

| Changed surface | Standards checked | Framework or domain docs checked
| Result |
| --- | --- | --- | --- |
| Release Management spec and design | Documentation Model, Naming,
Markdown | Applicability, defaults, overrides, and decision validation |
Aligned |
| VS Code framework design | Documentation Model, Naming, Markdown |
Existing extension interface and release configuration | Aligned |
| Automation Labels and PR Format | Natural Language, Markdown, owning
standards | Release-route applicability and complete-record ownership |
Aligned |

The accepted release-range-first analysis, complete description example
with one summary boundary, conditional release/default rules, Task/Bug
planning, and repository-owned no-PR-template policy are preserved
without tests of their prose. Runtime default/migration work belongs to
PSModule/Release-GHRepository#109, not this source. No module file,
loader, public input, Build/metadata/runtime schema, publisher, pin,
permission, ruleset, marketplace, or consumer fleet change is included.

</details>

<details>
<summary>Related references</summary>

- References PSModule/Release-GHRepository#109
- References #196
- References #208
- References #209

</details>

## Changed: Documentation builds regenerate indexes without a drift gate

CI generates documentation indexes before building the site instead of
rejecting an out-of-date generated table. A documentation edit no longer
needs to satisfy an index-drift gate. The generator updates only the
build checkout; this change adds no bot commit or source
synchronization.

Optional local `-Check` diagnostics and functional tests of the
generator remain available. Linting, link validation, and site builds
still run. The contribution guide and script help describe this
distinction; no tests inspect the actual workflow to enforce its
contents.

<details>
<summary>Technical details</summary>

| Changed surface | Standards checked | Framework or domain docs checked
| Result |
| --- | --- | --- | --- |
| `.github/workflows/Docs.yml` | GitHub Actions, YAML | Existing
documentation build pipeline | Aligned |
| `.github/scripts/Update-DocumentationIndex.ps1` (help only) |
PowerShell, Natural Language | Existing index generator interface |
Aligned |
| `.github/CONTRIBUTING.md` | Markdown, contribution guidance |
Documentation authoring and build flow | Aligned |

The index step runs normal generation with no `-Check` flag. The
index-generator implementation and all functional test suites are
unchanged. The local generation-then-build path succeeds with
repository-pinned Zensical 0.0.59; the changed contribution guidance is
lint-clean and the scoped diff has no whitespace errors. The exact-head
CI Build job also successfully executes `Generate documentation indexes`
followed by the site build. Temporary build environments and output are
cleaned without changing shared dependencies.

The Task records the audit, the user's selected boundary, and the
completed verification. Its implementation and review gates are
complete; the Task remains open for reviewed integration. This PR
remains draft; native maintenance has `merge_pr=false`, GitHub
auto-merge is off, and no live publication or merge is authorized. A
later main change requires a refreshed comparison and exact-head
validation.

</details>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:major Publish a major release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resolve repository releases from owned decisions and effective settings

2 participants