Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3eba878
Reproduce publication without source-bound preflight
MariusStorhaug Oct 31, 2026
2607da2
Bind immutable publication claims to source and tested bytes
MariusStorhaug Oct 31, 2026
6b5ffcd
Verify publication resources and create version claims atomically
MariusStorhaug Oct 31, 2026
ee65fa7
Preflight Gallery writes and preserve release-side ownership rechecks
MariusStorhaug Oct 31, 2026
c3b9ff4
Stop version resolution on unverifiable Gallery reads
MariusStorhaug Oct 31, 2026
84fcb9c
Isolate artifact fixtures for shuffled action tests
MariusStorhaug Oct 31, 2026
4cf52d8
Document source-bound publication and immutable retry requirements
MariusStorhaug Oct 31, 2026
857795a
Select Gallery recovery versions only from immutable source and raw p…
MariusStorhaug Oct 31, 2026
db90fa3
Reproduce Gallery success GitHub failure and exact-byte retry end to end
MariusStorhaug Oct 31, 2026
afe5fbc
Document proven original-version recovery and safe legacy failures
MariusStorhaug Oct 31, 2026
438c7d0
Reject invalid producing context and changed claims before release mu…
MariusStorhaug Oct 31, 2026
982f3dd
Require verified prerelease enumeration metadata before choosing a co…
MariusStorhaug Oct 31, 2026
d4b206a
Preserve malformed JSON array shape and literal artifact filenames
MariusStorhaug Oct 31, 2026
e20d41a
Reserve immutable module versions independently of release tag prefixes
MariusStorhaug Oct 31, 2026
5fb356b
Document shared package ownership and tested version binding
MariusStorhaug Oct 31, 2026
f68b14a
Validate original resolver context before projection and bind shared …
MariusStorhaug Oct 31, 2026
61f81ff
Reproduce lost release tags during shared publication reservation
MariusStorhaug Oct 31, 2026
ff6bf3f
Reject observed tag changes during shared module version reservation
MariusStorhaug Oct 31, 2026
6abfb43
Reproduce coerced provenance and inconsistent release archive proof
MariusStorhaug Oct 31, 2026
85003e1
Reproduce original event context projection before publisher validation
MariusStorhaug Oct 31, 2026
c2542d4
Reject projected provenance and inconsistent release archive claims
MariusStorhaug Oct 31, 2026
2c4ecf6
Reproduce shared-only claims and historical-prefix recovery baselines
MariusStorhaug Oct 31, 2026
c665a9b
Discover shared-only claims and verify actual historical release base…
MariusStorhaug Oct 31, 2026
53b32f3
Reproduce terminal provenance, raw metadata and module ref compatibil…
MariusStorhaug Oct 31, 2026
085036b
Require terminal ownership proof and typed publication metadata
MariusStorhaug Oct 31, 2026
c47584b
Reproduce projected resolver tag collection metadata
MariusStorhaug Oct 31, 2026
e2e282a
Require a verified tag collection for source claim discovery
MariusStorhaug Oct 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions .github/actions/Publish-PSModule/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# Publish-PSModule

Publishes a pre-versioned PowerShell module artifact to the PowerShell Gallery. GitHub Release creation is intentionally handled by the separate [Release-PSModule](../Release-PSModule/README.md) action.
Publishes a pre-versioned, tested PowerShell module artifact to the PowerShell Gallery after source-bound ownership preflight. GitHub Release creation is handled by the separate [Release-PSModule](../Release-PSModule/README.md) action.

The publisher verifies the original source, exact resolved tag/version, producing repository/PR or direct-release context, and tested bytes before an external versioned-artifact mutation. An absent Gallery module/version is reserved at `PSModule-Publication/<escaped-lowercase-module>/<lowercase-version>`, independently of the configured release-tag prefix. Module-name dots are encoded as `%2e` so valid dotted names cannot produce Git-invalid `..` or `.lock` components. The shared coordinate and release tag reference the same immutable annotated source/context/file-tree/ZIP claim. Existing tags are never updated or deleted; the package ownership coordinate is retained for immutable Gallery proof.

An observed release tag must remain unchanged through shared coordinate creation. If it disappears or is replaced during that reservation, the attempt fails instead of recreating it. A valid partial shared claim can still create an absent release tag that has never been observed in the attempt.

An existing Gallery package is retained only when its raw nupkg payload matches that proof and the tested artifact. Package code is never imported to establish ownership. Unknown legacy proof, foreign tags/releases/assets, changed claims, authentication errors, and API failures stop publication explicitly.

Provenance must contain one original JSON object with scalar proof fields; arrays are not projected into valid identities. The ZIP's exact bytes and canonical payload digest are verified together against the tested file tree before a claim or Gallery write. Original event PR context is validated before normalized fields are selected.

GitHub resource responses must have valid object/scalar shapes, while verified empty tag collections remain valid absence. An existing PR-produced stable or prerelease release requires its producing-context footer; unreadable terminal markers are errors even when indented or inline. Unknown legacy PR release context is not inferred from a matching tag.

## Inputs

Expand All @@ -10,6 +20,10 @@ Publishes a pre-versioned PowerShell module artifact to the PowerShell Gallery.
| `ModulePath` | Path containing the built `<Name>/` module directory. | No | `.PSModule/module` |
| `ArtifactName` | Name of the module artifact to download. | No | `module` |
| `PSGALLERY_API_KEY` | PowerShell Gallery API key. | Yes | N/A |
| `ReleaseTag` | Exact tag already resolved as `Publish.Module.Resolution.FullVersion`. | Yes | N/A |
| `VersionPrefix` | Existing resolver prefix used to bind `ReleaseTag` to the tested module version. | No | `v` |
| `CommitSha` | Immutable commit that produced the tested artifact. | No | Original workflow `GITHUB_SHA` |
| `PullRequest` | Normalized producing-PR context; empty for a direct stable release. | No | Empty |
| `WhatIf` | Logs publishing operations without publishing the module. | No | `false` |
| `WorkingDirectory` | Directory where the publishing script runs. | No | `.` |

Expand All @@ -27,6 +41,14 @@ This action does not provide outputs.
ModulePath: .PSModule/module
ArtifactName: module
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
ReleaseTag: ${{ fromJson(inputs.Settings).Publish.Module.Resolution.FullVersion }}
VersionPrefix: ${{ fromJson(inputs.Settings).Publish.Module.VersionPrefix }}
CommitSha: ${{ fromJson(inputs.Settings).Context.CommitSha }}
PullRequest: ${{ toJson(fromJson(inputs.Settings).Context.PullRequest) }}
```

Use [Release-PSModule](../Release-PSModule/README.md) in a separate workflow step to create the GitHub release from the same artifact.
Provide `GH_TOKEN` with contents-write access scoped to the consumer repository. The reusable workflow supplies its existing GitHub App token and resolved context internally.

NuGet-reserved container metadata paths are rejected in the tested candidate before a claim or upload, using the same path classification as raw package verification. A published package without its shared module/version coordinate is unproven; the publisher does not fabricate that ownership record on retry.

Use [Release-PSModule](../Release-PSModule/README.md) in a separate step to create the GitHub release from the same source and tested artifact. A retry must retain the original coordinates and bytes; unproven legacy publication requires reviewed forward-only recovery, not numeric guessing, retagging, or metadata changes.
14 changes: 14 additions & 0 deletions .github/actions/Publish-PSModule/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ inputs:
description: Normalized pull request context JSON from Get-PSModuleSettings.
required: false
default: ''
ReleaseTag:
description: Exact GitHub tag already resolved for the tested module artifact.
required: true
VersionPrefix:
description: Configured prefix used by the existing resolver; verifies the tag against the tested module version.
required: false
default: v
CommitSha:
description: Immutable commit that produced the tested module artifact; defaults to the original workflow SHA.
required: false
default: ''
WhatIf:
description: If specified, the action will only log the changes it would make, but will not publish the module.
required: false
Expand Down Expand Up @@ -55,5 +66,8 @@ runs:
PSMODULE_PUBLISH_PSMODULE_INPUT_ModulePath: ${{ inputs.ModulePath }}
PSMODULE_PUBLISH_PSMODULE_INPUT_PSGALLERY_API_KEY: ${{ inputs.PSGALLERY_API_KEY }}
PSMODULE_PUBLISH_PSMODULE_INPUT_PullRequest: ${{ inputs.PullRequest }}
PSMODULE_PUBLISH_PSMODULE_INPUT_ReleaseTag: ${{ inputs.ReleaseTag }}
PSMODULE_PUBLISH_PSMODULE_INPUT_VersionPrefix: ${{ inputs.VersionPrefix }}
PSMODULE_PUBLISH_PSMODULE_INPUT_CommitSha: ${{ inputs.CommitSha || github.sha }}
PSMODULE_PUBLISH_PSMODULE_INPUT_WhatIf: ${{ inputs.WhatIf }}
run: ${{ github.action_path }}/src/publish.ps1
Loading
Loading