mirror of
https://github.com/MAKS-IT-COM/maksit-certs-ui.git
synced 2026-05-16 12:58:11 +02:00
162 lines
5.9 KiB
PowerShell
162 lines
5.9 KiB
PowerShell
#requires -Version 7.0
|
|
#requires -PSEdition Core
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Central gate for publish-stage plugins (Docker, Helm, GitHub, NuGet).
|
|
|
|
.DESCRIPTION
|
|
Place this plugin immediately before any publish plugins in scriptsettings.json. It sets
|
|
shared context skipPublishPlugins to false when all configured requirements pass, or true
|
|
when they do not (whenRequirementsNotMet: skip). Publish plugins no longer use per-plugin
|
|
branch lists; put allowed branches here instead.
|
|
|
|
Typical checks: allowed branches, optional clean working tree, exact semver tag on HEAD,
|
|
tag version vs DotNetReleaseVersion, optional push tag to remote.
|
|
|
|
The engine preflight no longer reads git tags; this plugin sets context.tag from the
|
|
git tag on HEAD when required. Shared context version always remains from DotNetReleaseVersion.
|
|
#>
|
|
|
|
if (-not (Get-Command Import-PluginDependency -ErrorAction SilentlyContinue)) {
|
|
$pluginSupportModulePath = Join-Path (Split-Path $PSScriptRoot -Parent) "PluginSupport.psm1"
|
|
if (Test-Path $pluginSupportModulePath -PathType Leaf) {
|
|
Import-Module $pluginSupportModulePath -Force -Global -ErrorAction Stop
|
|
}
|
|
}
|
|
|
|
function Get-ExactTagOnHeadSilentlyInternal {
|
|
$raw = & git describe --tags --exact-match HEAD 2>&1
|
|
if ($LASTEXITCODE -ne 0) {
|
|
return $null
|
|
}
|
|
$s = ($raw | Out-String).Trim()
|
|
if ([string]::IsNullOrWhiteSpace($s)) {
|
|
return $null
|
|
}
|
|
return $s
|
|
}
|
|
|
|
function Invoke-NotMetInternal {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
$Shared,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$When,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Reason
|
|
)
|
|
|
|
$Shared | Add-Member -NotePropertyName skipPublishPlugins -NotePropertyValue $true -Force
|
|
if ($When -eq 'fail') {
|
|
Write-Log -Level "ERROR" -Message "ReleasePublishGuard: $Reason"
|
|
exit 1
|
|
}
|
|
|
|
Write-Log -Level "WARN" -Message " Publish suppressed: $Reason"
|
|
}
|
|
|
|
function Invoke-Plugin {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
$Settings
|
|
)
|
|
|
|
Import-PluginDependency -ModuleName "Logging" -RequiredCommand "Write-Log"
|
|
$pluginSupportPath = Join-Path (Split-Path $PSScriptRoot -Parent) "PluginSupport.psm1"
|
|
Import-Module $pluginSupportPath -Force -Global -ErrorAction Stop
|
|
|
|
Import-PluginDependency -ModuleName "GitTools" -RequiredCommand "Get-GitStatusShort"
|
|
Import-PluginDependency -ModuleName "GitTools" -RequiredCommand "Test-RemoteTagExists"
|
|
Import-PluginDependency -ModuleName "GitTools" -RequiredCommand "Push-TagToRemote"
|
|
|
|
$pluginSettings = $Settings
|
|
$shared = $Settings.context
|
|
$when = 'skip'
|
|
if ($null -ne $pluginSettings.whenRequirementsNotMet) {
|
|
$when = [string]$pluginSettings.whenRequirementsNotMet
|
|
}
|
|
if ($when -notin @('skip', 'fail')) {
|
|
throw "ReleasePublishGuard: whenRequirementsNotMet must be 'skip' or 'fail'."
|
|
}
|
|
|
|
$shared | Add-Member -NotePropertyName skipPublishPlugins -NotePropertyValue $false -Force
|
|
|
|
Write-Log -Level "STEP" -Message "Release publish guard..."
|
|
|
|
$allowed = @(Get-PluginBranches -Plugin $pluginSettings)
|
|
if ($allowed.Count -gt 0 -and $allowed -notcontains '*' -and $allowed -notcontains $shared.currentBranch) {
|
|
Invoke-NotMetInternal -Shared $shared -When $when -Reason "branch '$($shared.currentBranch)' is not in the guard branches list."
|
|
return
|
|
}
|
|
|
|
$requireClean = $false
|
|
if ($null -ne $pluginSettings.requireCleanWorkingTree) {
|
|
$requireClean = [bool]$pluginSettings.requireCleanWorkingTree
|
|
}
|
|
if ($requireClean) {
|
|
$dirtyRaw = Get-GitStatusShort
|
|
if (-not [string]::IsNullOrWhiteSpace([string]$dirtyRaw)) {
|
|
Invoke-NotMetInternal -Shared $shared -When $when -Reason "working tree is not clean (requireCleanWorkingTree is true)."
|
|
return
|
|
}
|
|
}
|
|
|
|
$requireTag = $true
|
|
if ($null -ne $pluginSettings.requireExactTagOnHead) {
|
|
$requireTag = [bool]$pluginSettings.requireExactTagOnHead
|
|
}
|
|
|
|
$tag = $null
|
|
if ($requireTag) {
|
|
$tag = Get-ExactTagOnHeadSilentlyInternal
|
|
if ([string]::IsNullOrWhiteSpace($tag)) {
|
|
Invoke-NotMetInternal -Shared $shared -When $when -Reason "no exact semver tag on HEAD (git describe --tags --exact-match)."
|
|
return
|
|
}
|
|
|
|
if ($tag -notmatch '^v(\d+\.\d+\.\d+)$') {
|
|
Invoke-NotMetInternal -Shared $shared -When $when -Reason "tag '$tag' must match vX.Y.Z."
|
|
return
|
|
}
|
|
|
|
$tagVersion = $Matches[1]
|
|
$mustMatch = $true
|
|
if ($null -ne $pluginSettings.tagVersionMustMatchDotNetRelease) {
|
|
$mustMatch = [bool]$pluginSettings.tagVersionMustMatchDotNetRelease
|
|
}
|
|
if ($mustMatch -and $tagVersion -ne [string]$shared.version) {
|
|
Invoke-NotMetInternal -Shared $shared -When $when -Reason "tag version $tagVersion does not match DotNet release version $($shared.version)."
|
|
return
|
|
}
|
|
|
|
$shared | Add-Member -NotePropertyName tag -NotePropertyValue $tag -Force
|
|
}
|
|
|
|
$ensureRemote = $true
|
|
if ($null -ne $pluginSettings.ensureTagOnRemote) {
|
|
$ensureRemote = [bool]$pluginSettings.ensureTagOnRemote
|
|
}
|
|
if ($ensureRemote -and $requireTag -and -not [string]::IsNullOrWhiteSpace($tag)) {
|
|
$remote = 'origin'
|
|
if (-not [string]::IsNullOrWhiteSpace([string]$pluginSettings.remoteName)) {
|
|
$remote = [string]$pluginSettings.remoteName
|
|
}
|
|
|
|
Write-Log -Level "STEP" -Message "Verifying tag on remote '$remote'..."
|
|
if (-not (Test-RemoteTagExists -Tag $tag -Remote $remote)) {
|
|
Write-Log -Level "WARN" -Message " Tag $tag not on remote. Pushing..."
|
|
Push-TagToRemote -Tag $tag -Remote $remote
|
|
}
|
|
else {
|
|
Write-Log -Level "OK" -Message " Tag exists on remote."
|
|
}
|
|
}
|
|
|
|
Write-Log -Level "OK" -Message " Publish guard passed; publish plugins will run."
|
|
}
|
|
|
|
Export-ModuleMember -Function Invoke-Plugin
|