CRM/scripts/package-release.ps1

83 خطوط
2.4 KiB
PowerShell

[CmdletBinding()]
param(
[string] $OutputPath = 'artifacts\crm-release.zip'
)
$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
$root = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
$output = if ([System.IO.Path]::IsPathRooted($OutputPath)) {
[System.IO.Path]::GetFullPath($OutputPath)
} else {
[System.IO.Path]::GetFullPath((Join-Path $root $OutputPath))
}
& git -C $root rev-parse --is-inside-work-tree | Out-Null
if ($LASTEXITCODE -ne 0) {
throw 'Release packaging requires a Git worktree.'
}
$status = @(& git -C $root status --porcelain --untracked-files=all)
if ($LASTEXITCODE -ne 0) {
throw 'Unable to inspect the Git worktree.'
}
if ($status.Count -gt 0) {
throw "The worktree is not clean. Commit the intended release first.`n$($status -join "`n")"
}
$tracked = @(& git -C $root ls-files)
if ($LASTEXITCODE -ne 0) {
throw 'Unable to list tracked release files.'
}
$forbiddenPathPatterns = @(
'(^|/)\.env($|\.(?!example$))',
'(^|/)(vendor|node_modules)(/|$)',
'(^|/)(storage/logs|bootstrap/cache)(/|$)',
'\.(sqlite|sqlite3|db)$',
'(^|/)(auth\.json|cookies[^/]*)$'
)
$forbidden = $tracked | Where-Object {
$path = $_
$forbiddenPathPatterns | Where-Object { $path -match $_ } | Select-Object -First 1
}
if ($forbidden) {
throw "Tracked forbidden files would enter the release:`n$($forbidden -join "`n")"
}
$secretPatterns = @(
'APP_KEY=base64:[A-Za-z0-9+/=]{20,}',
'(sk|ghp|github_pat)_[A-Za-z0-9_-]{20,}',
'-----BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY-----'
)
foreach ($pattern in $secretPatterns) {
$matches = @(& git -C $root grep -I -n -E -- $pattern -- . 2>$null)
if ($pattern.StartsWith('APP_KEY=')) {
$matches = @($matches | Where-Object { $_ -notmatch 'APP_KEY=base64:A{43}=' })
}
if ($LASTEXITCODE -eq 0 -and $matches.Count -gt 0) {
throw "A possible secret was detected in tracked content:`n$($matches -join "`n")"
}
if ($LASTEXITCODE -gt 1) {
throw 'Secret scan failed.'
}
}
$outputDirectory = Split-Path -Parent $output
New-Item -ItemType Directory -Force -Path $outputDirectory | Out-Null
if (Test-Path -LiteralPath $output) {
Remove-Item -LiteralPath $output -Force
}
& git -C $root archive --format=zip --output=$output HEAD
if ($LASTEXITCODE -ne 0) {
throw 'git archive failed.'
}
$hash = (Get-FileHash -Algorithm SHA256 -LiteralPath $output).Hash
Write-Host "Release archive: $output"
Write-Host "SHA256: $hash"