Public/Install-PCReleaseWorkflow.ps1

<#
.SYNOPSIS
    Installs CI and Release workflow templates into a target repository.
.DESCRIPTION
    Copies standardised GitHub Actions workflow files from the PowerCraft.Release
    module's Templates/ folder into the target repository's .github/workflows/ directory.

    The release.yml template contains a {{MODULE_NAME}} token that is replaced with
    the detected module name from the .psd1 file in the target directory.

    CI workflow (ci.yml) is copied as-is — it is generic across all PS modules.
.PARAMETER Path
    Target repository root directory. Defaults to current directory.
.PARAMETER Force
    Overwrite existing workflow files without prompting.
.EXAMPLE
    Install-PCReleaseWorkflow
    # Installs workflows into current directory's .github/workflows/
.EXAMPLE
    Install-PCReleaseWorkflow -Path C:\repos\MyModule -Force
    # Overwrites any existing workflows
.OUTPUTS
    [PSCustomObject[]] List of files created/updated.
#>

function Install-PCReleaseWorkflow {
    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([PSCustomObject[]])]
    param(
        [Parameter()]
        [string]$Path = (Get-Location).Path,

        [switch]$Force
    )

    $templateDir = Join-Path $PSScriptRoot '..' 'Templates'
    if (-not (Test-Path $templateDir)) {
        throw "Templates directory not found at '$templateDir'. Module may be incorrectly installed."
    }

    # Detect module name from .psd1
    $psd1 = Get-ChildItem -Path $Path -Filter '*.psd1' -File | Select-Object -First 1
    if (-not $psd1) {
        throw "No .psd1 file found in '$Path'. This command targets PowerShell module repositories."
    }
    $moduleName = $psd1.BaseName
    Write-Verbose "Detected module: $moduleName"

    # Ensure .github/workflows exists
    $workflowDir = Join-Path $Path '.github' 'workflows'
    if (-not (Test-Path $workflowDir)) {
        New-Item -ItemType Directory -Path $workflowDir -Force | Out-Null
        Write-Verbose "Created: $workflowDir"
    }

    $results = @()

    # Install ci.yml (generic, no tokens)
    $ciSource = Join-Path $templateDir 'ci.yml'
    $ciTarget = Join-Path $workflowDir 'ci.yml'
    if ((Test-Path $ciTarget) -and -not $Force) {
        Write-Warning "ci.yml already exists. Use -Force to overwrite."
        $results += [PSCustomObject]@{ File = 'ci.yml'; Status = 'Skipped'; Reason = 'Already exists' }
    }
    elseif ($PSCmdlet.ShouldProcess($ciTarget, "Install ci.yml workflow")) {
        Copy-Item -Path $ciSource -Destination $ciTarget -Force
        $results += [PSCustomObject]@{ File = 'ci.yml'; Status = 'Installed'; Reason = '' }
    }

    # Install release.yml (replace {{MODULE_NAME}} token)
    $releaseSource = Join-Path $templateDir 'release.yml'
    $releaseTarget = Join-Path $workflowDir 'release.yml'
    if ((Test-Path $releaseTarget) -and -not $Force) {
        Write-Warning "release.yml already exists. Use -Force to overwrite."
        $results += [PSCustomObject]@{ File = 'release.yml'; Status = 'Skipped'; Reason = 'Already exists' }
    }
    elseif ($PSCmdlet.ShouldProcess($releaseTarget, "Install release.yml workflow (module: $moduleName)")) {
        $content = Get-Content -Path $releaseSource -Raw
        $content = $content -replace '\{\{MODULE_NAME\}\}', $moduleName
        Set-Content -Path $releaseTarget -Value $content -NoNewline
        $results += [PSCustomObject]@{ File = 'release.yml'; Status = 'Installed'; Reason = '' }
    }

    # Install dependency-check.yml (only if module has RequiredModules)
    $depCheckSource = Join-Path $templateDir 'dependency-check.yml'
    $depCheckTarget = Join-Path $workflowDir 'dependency-check.yml'
    $manifestData = Import-PowerShellDataFile $psd1.FullName
    if ($manifestData.RequiredModules) {
        if ((Test-Path $depCheckTarget) -and -not $Force) {
            Write-Warning "dependency-check.yml already exists. Use -Force to overwrite."
            $results += [PSCustomObject]@{ File = 'dependency-check.yml'; Status = 'Skipped'; Reason = 'Already exists' }
        }
        elseif ($PSCmdlet.ShouldProcess($depCheckTarget, "Install dependency-check.yml workflow")) {
            Copy-Item -Path $depCheckSource -Destination $depCheckTarget -Force
            $results += [PSCustomObject]@{ File = 'dependency-check.yml'; Status = 'Installed'; Reason = '' }
        }
    }

    # Remove old publish.yml if present (superseded by release.yml)
    $publishYml = Join-Path $workflowDir 'publish.yml'
    if (Test-Path $publishYml) {
        Write-Host " Found legacy publish.yml — consider removing it (superseded by release.yml)" -ForegroundColor Yellow
    }

    # Summary
    Write-Host "`nWorkflow installation for '$moduleName':" -ForegroundColor Cyan
    foreach ($r in $results) {
        $color = if ($r.Status -eq 'Installed') { 'Green' } else { 'Yellow' }
        $detail = if ($r.Reason) { " ($($r.Reason))" } else { '' }
        Write-Host " $($r.File): $($r.Status)$detail" -ForegroundColor $color
    }

    Write-Host "`nReminder:" -ForegroundColor Cyan
    Write-Host " Ensure PSGALLERY_API_KEY secret is set:" -ForegroundColor White
    Write-Host " gh secret set PSGALLERY_API_KEY --repo <owner>/<repo>" -ForegroundColor Gray

    return $results
}