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 = '' } } # 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 } |