Private/Migration/Invoke-CgrNewDestinationFullHistory.ps1

function Invoke-CgrNewDestinationFullHistory {
    <#
    .SYNOPSIS
    Orchestrates verified FullHistory publication to a newly created destination.

    .DESCRIPTION
    Copies approved history, reloads and verifies the destination, restores supported
    settings and protection only after content verification, and records ordered
    completion or recovery evidence. Verification failure intentionally stops the
    configuration-restore stages.

    .NOTES
    The destination repository has already been created when this function begins.
    Public ShouldProcess consent is owned by Copy-GitHubRepository; this boundary
    owns fail-safe sequencing and recovery reporting after mutation has started.
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'The public Copy-GitHubRepository command performs ShouldProcess before calling this orchestration boundary.')]
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)] [psobject] $Plan,
        [Parameter(Mandatory)] [psobject] $SourceRepository,
        [Parameter(Mandatory)] [psobject] $DestinationRepository,
        [ValidateNotNullOrEmpty()] [string] $HostName = 'github.com',
        [string] $ReportPath
    )

    $completedSteps = [System.Collections.Generic.List[object]]::new()
    $completedSteps.Add([pscustomobject] @{ Order = 1; Name = 'CreateDestinationRepository'; MutatedGitHub = $true; Verified = $true })
    $failureStage = 'CopyFullHistory'
    $sourceState = Get-CgrObjectProperty -InputObject $Plan -Name 'SourceState'
    $copyResult = $null

    try {
        $copyResult = Copy-CgrRepositoryFullHistory -SourceRepository $SourceRepository -DestinationRepository $DestinationRepository -HostName $HostName -ApprovedSourceState $sourceState
        $completedSteps.Add([pscustomobject] @{ Order = 2; Name = 'CopyFullHistory'; MutatedGitHub = $true; Verified = $copyResult.IsSuccessful })

        $failureStage = 'ReloadDestination'
        $verifiedDestination = Get-CgrRepository -Repository $DestinationRepository.FullName -HostName $HostName

        $failureStage = 'VerifyFullHistory'
        $verification = Invoke-CgrActivityStage -Name 'VerifyDestinationContent' -Message 'Verify destination content' -Action {
            if ($sourceState) {
                return Invoke-CgrApprovedFullHistoryVerification -SourceRepository $SourceRepository -DestinationRepository $verifiedDestination -ApprovedSourceState $sourceState
            }
            Invoke-CgrRepositoryFullHistoryVerification -SourceRepository $SourceRepository -DestinationRepository $verifiedDestination
        }
        $completedSteps.Add([pscustomobject] @{ Order = 3; Name = 'VerifyFullHistory'; MutatedGitHub = $false; Verified = $verification.IsSuccessful })

        $failureStage = 'RestoreSupportedSettings'
        $settings = Invoke-CgrActivityStage -Name 'RestoreSupportedSettings' -Message 'Restore supported repository settings' -Action {
            if (-not $verification.IsSuccessful) {
                return [pscustomobject] @{ PSTypeName = 'CopyGitHubRepo.SettingsRestoreResult'; Repository = $DestinationRepository.FullName; Restored = @(); Skipped = @('FullHistoryVerificationFailed'); Unsupported = @(); IsSuccessful = $false }
            }
            if ($Plan.SkipSettings) {
                return [pscustomobject] @{ PSTypeName = 'CopyGitHubRepo.SettingsRestoreResult'; Repository = $DestinationRepository.FullName; Restored = @(); Skipped = @('AllSettings'); Unsupported = @(); IsSuccessful = $true }
            }
            Set-CgrGitHubRepositorySetting -SourceRepository $SourceRepository -DestinationRepository $verifiedDestination -HostName $HostName
        }
        $completedSteps.Add([pscustomobject] @{ Order = 4; Name = 'RestoreSupportedSettings'; MutatedGitHub = -not $Plan.SkipSettings; Verified = $settings.IsSuccessful })

        $failureStage = 'RestoreRepositoryProtection'
        $planProtection = Get-CgrObjectProperty -InputObject $Plan -Name 'Protection'
        $protection = Invoke-CgrActivityStage -Name 'RestoreRepositoryProtection' -Message 'Restore transferable repository protection' -Action {
            if (-not $verification.IsSuccessful) {
                return [pscustomobject] @{ PSTypeName = 'CopyGitHubRepo.RepositoryProtectionRestoreResult'; Repository = $DestinationRepository.FullName; Status = 'Failed'; Restored = @(); Skipped = @('FullHistoryVerificationFailed'); IsSuccessful = $false; IsComplete = $false }
            }
            if ($Plan.SkipSettings) {
                return [pscustomobject] @{ PSTypeName = 'CopyGitHubRepo.RepositoryProtectionRestoreResult'; Repository = $DestinationRepository.FullName; Status = 'Skipped'; Restored = @(); Skipped = @('AllSettings'); IsSuccessful = $true; IsComplete = $true }
            }
            if ($planProtection -and (Get-CgrObjectProperty -InputObject $planProtection -Name 'Status') -eq 'Captured') {
                return Set-CgrRepositoryProtectionConfiguration -SourceRepository $SourceRepository -DestinationRepository $verifiedDestination -SourceConfiguration (Get-CgrObjectProperty -InputObject $planProtection -Name 'Configuration') -HostName $HostName
            }
            Set-CgrRepositoryProtectionConfiguration -SourceRepository $SourceRepository -DestinationRepository $verifiedDestination -HostName $HostName
        }
        $completedSteps.Add([pscustomobject] @{ Order = 5; Name = 'RestoreRepositoryProtection'; MutatedGitHub = [bool] ($verification.IsSuccessful -and -not $Plan.SkipSettings); Verified = $protection.IsSuccessful })

        $copiedSourceEvidence = Get-CgrObjectProperty -InputObject $copyResult -Name 'CopiedSourceEvidence'
        $executionResult = [pscustomobject] @{
            PSTypeName = 'CopyGitHubRepo.MigrationExecutionResult'
            SchemaVersion = 1
            Status = if (-not $verification.IsSuccessful) { 'FullHistoryVerificationFailed' } elseif ($Plan.SkipSettings) { 'FullHistoryVerifiedSettingsSkipped' } elseif ($settings.IsSuccessful -and $protection.IsSuccessful) { 'CompletedWithSupportedSettings' } elseif (-not $settings.IsSuccessful) { 'SettingsRestoreFailed' } else { 'ProtectionRestoreFailed' }
            SourceRepository = $Plan.SourceRepository
            ApprovedSourceState = $sourceState
            ActualCopiedSourceState = $copiedSourceEvidence
            DestinationRepository = $DestinationRepository.FullName
            SourceVisibility = $Plan.SourceVisibility
            DestinationVisibility = $Plan.DestinationVisibility
            DestinationHtmlUrl = $DestinationRepository.HtmlUrl
            DestinationBranch = $copyResult.DefaultBranch
            SnapshotCommitSha = $null
            IsVerified = $verification.IsSuccessful
            Verification = $verification
            Settings = $settings
            Protection = $protection
            Plan = $Plan
            CompletedSteps = @($completedSteps)
            StoppedBeforeSettingsRestore = -not $verification.IsSuccessful
            SettingsRestored = [bool] ($verification.IsSuccessful -and -not $Plan.SkipSettings -and $settings.IsSuccessful)
            ProtectionRestored = [bool] ($verification.IsSuccessful -and -not $Plan.SkipSettings -and $protection.IsSuccessful -and $protection.IsComplete)
        }

        if ($ReportPath) {
            $failureStage = 'WriteCompletionReport'
            Write-CgrMigrationExecutionReport -Result $executionResult -Path $ReportPath | Out-Null
        }
        return $executionResult
    }
    catch {
        $recoveryReportPath = $null
        try {
            $recoveryProvenance = [pscustomobject] @{
                ContentMode = 'FullHistory'
                PlannedSourceState = $sourceState
                ActualCopiedSourceState = if ($copyResult) { Get-CgrObjectProperty -InputObject $copyResult -Name 'CopiedSourceEvidence' } else { $null }
            }
            $recoveryReportPath = Write-CgrMigrationRecoveryReport -Plan $Plan -DestinationRepository $DestinationRepository -FailureStage $failureStage -ErrorRecord $_ -CompletedSteps @($completedSteps) -Provenance $recoveryProvenance -PreferredReportPath $ReportPath
        }
        catch { Write-Warning "FullHistory copy failed after destination creation, and the recovery report could not be written. Recovery reporting error: $($_.Exception.Message)" }
        if ($recoveryReportPath) { Write-Warning "FullHistory copy failed after destination creation. Recovery report: $recoveryReportPath" }
        throw
    }
}