Public/Publish-KadenRelease.ps1

function Publish-KadenRelease {
    <#
    .SYNOPSIS
        Publish one immutable Gallery version when provenance and key readiness already pass.
    .DESCRIPTION
        Tag, ProvenanceEligible, KeyReady, and VersionAlreadyPublished are facts supplied
        by the caller. This command does not take a Gallery API key. -PublishAction is the
        driven publish step. The workflow holds the Gallery key and passes only the module
        version into that step. A failed check names one KDN-RELEASE requirement, does not
        call the publish step, and does not write the release record or the changelog line.
        A version that is already public is not replaced.
    .EXAMPLE
        Publish-KadenRelease -Tag v1.2.3 -ProvenanceEligible $true -KeyReady $true -VersionAlreadyPublished $false -RecordPath .\publish-record.json -ChangelogPath .\CHANGELOG.md
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Tag,

        [Parameter(Mandatory = $true)]
        [bool]$ProvenanceEligible,

        [string]$ProvenanceFailure,

        [Parameter(Mandatory = $true)]
        [bool]$KeyReady,

        [string]$KeyFailure,

        [Parameter(Mandatory = $true)]
        [bool]$VersionAlreadyPublished,

        [string]$RecordPath,

        [string]$ChangelogPath,

        [scriptblock]$PublishAction
    )

    $decision = Get-KadenReleasePublishDecision -Tag $Tag -ProvenanceEligible $ProvenanceEligible `
        -ProvenanceFailure ([string]$ProvenanceFailure) -KeyReady $KeyReady -KeyFailure ([string]$KeyFailure) `
        -VersionAlreadyPublished $VersionAlreadyPublished
    $moduleVersion = $decision.ModuleVersion
    $recordedTag = $decision.Tag
    $failed = $decision.FailedRequirement

    if (-not $failed -and $PublishAction) {
        try {
            & $PublishAction $moduleVersion
        }
        catch {
            $failed = 'KDN-RELEASE-PUBLISH-FAILED: Publication did not complete.'
        }
    }

    $published = -not $failed
    $result = [pscustomobject]@{
        Published         = [bool]$published
        Replaced          = $false
        Tag               = $recordedTag
        ModuleVersion     = $moduleVersion
        FailedRequirement = $failed
    }

    if ($published -and -not [string]::IsNullOrWhiteSpace($RecordPath)) {
        Write-KadenJsonAtomic -LiteralPath $RecordPath -Object $result
    }
    if ($published -and -not [string]::IsNullOrWhiteSpace($ChangelogPath)) {
        Add-KadenChangelogReleaseLine -LiteralPath $ChangelogPath -Tag $recordedTag -ModuleVersion $moduleVersion
    }

    return $result
}