368 lines
10 KiB
PowerShell
368 lines
10 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Automatyczne budowanie paczki aktualizacji cmsPRO na podstawie git diff miedzy tagami.
|
|
|
|
.DESCRIPTION
|
|
Skrypt porownuje dwa tagi git, filtruje pliki przez .updateignore,
|
|
tworzy ZIP + manifest JSON i aktualizuje changelog.php oraz versions.php.
|
|
|
|
.PARAMETER FromTag
|
|
Tag poczatkowy (np. v1.689). Domyslnie: ostatni tag.
|
|
|
|
.PARAMETER ToTag
|
|
Tag docelowy (np. v1.690). Wymagany.
|
|
|
|
.PARAMETER ChangelogEntry
|
|
Wpis do changelogu. Wymagany (chyba ze -DryRun).
|
|
|
|
.PARAMETER DryRun
|
|
Tylko pokaz co zostaloby zrobione, bez tworzenia plikow.
|
|
|
|
.EXAMPLE
|
|
./build-update.ps1 -ToTag v1.690 -ChangelogEntry "NEW - nowa funkcja"
|
|
./build-update.ps1 -FromTag v1.689 -ToTag v1.690 -ChangelogEntry "NEW - opis" -DryRun
|
|
#>
|
|
|
|
param(
|
|
[string]$FromTag = "",
|
|
[Parameter(Mandatory=$true)]
|
|
[string]$ToTag,
|
|
[string]$ChangelogEntry = "",
|
|
[switch]$DryRun
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
$Utf8NoBom = New-Object System.Text.UTF8Encoding $false
|
|
|
|
# --- Helpers ---
|
|
|
|
function Write-Step($msg) {
|
|
Write-Host " [*] $msg" -ForegroundColor Cyan
|
|
}
|
|
|
|
function Write-Ok($msg) {
|
|
Write-Host " [OK] $msg" -ForegroundColor Green
|
|
}
|
|
|
|
function Write-Warn($msg) {
|
|
Write-Host " [!] $msg" -ForegroundColor Yellow
|
|
}
|
|
|
|
function Write-Err($msg) {
|
|
Write-Host " [ERROR] $msg" -ForegroundColor Red
|
|
}
|
|
|
|
# --- 1. Walidacja tagow ---
|
|
|
|
Write-Host "`n=== cmsPRO Build Update ===" -ForegroundColor White
|
|
|
|
if (-not $FromTag) {
|
|
$FromTag = (git describe --tags --abbrev=0 2>$null)
|
|
if (-not $FromTag) {
|
|
Write-Err "Nie znaleziono zadnego taga. Uzyj parametru -FromTag."
|
|
exit 1
|
|
}
|
|
Write-Step "Auto-detect FromTag: $FromTag"
|
|
}
|
|
|
|
# Sprawdz czy tagi istnieja
|
|
$tagExists = git tag -l $FromTag
|
|
if (-not $tagExists) {
|
|
Write-Err "Tag '$FromTag' nie istnieje."
|
|
exit 1
|
|
}
|
|
|
|
$toTagExists = git tag -l $ToTag
|
|
if (-not $toTagExists) {
|
|
Write-Warn "Tag '$ToTag' nie istnieje. Uzywam HEAD jako punktu docelowego."
|
|
$diffTarget = "HEAD"
|
|
} else {
|
|
$diffTarget = $ToTag
|
|
}
|
|
|
|
# --- 2. Wersja i katalog ---
|
|
|
|
$versionNumber = $ToTag -replace '^v', ''
|
|
$versionInt = [int]($versionNumber -replace '\.', '')
|
|
|
|
# Oblicz katalog: 1.689 -> "1.6" + "0" -> "1.60"
|
|
$dirStr = $versionNumber.Substring(0, $versionNumber.Length - 2) + "0"
|
|
|
|
Write-Step "Wersja: $versionNumber (int: $versionInt)"
|
|
Write-Step "Katalog: updates/$dirStr/"
|
|
|
|
# --- 3. Git diff ---
|
|
|
|
Write-Step "Porownywanie: $FromTag..$diffTarget"
|
|
|
|
$diffOutput = git diff --name-status "$FromTag..$diffTarget" 2>&1
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Err "git diff nie powiodl sie: $diffOutput"
|
|
exit 1
|
|
}
|
|
|
|
$addedFiles = @()
|
|
$modifiedFiles = @()
|
|
$deletedFiles = @()
|
|
$renamedFiles = @()
|
|
|
|
foreach ($line in ($diffOutput -split "`n")) {
|
|
$line = $line.Trim()
|
|
if (-not $line) { continue }
|
|
|
|
$parts = $line -split "`t"
|
|
$status = $parts[0]
|
|
$filePath = if ($parts.Count -gt 1) { $parts[1] } else { "" }
|
|
|
|
# Zamien backslash na slash
|
|
$filePath = $filePath -replace '\\', '/'
|
|
|
|
switch -Wildcard ($status) {
|
|
"A" { $addedFiles += $filePath }
|
|
"M" { $modifiedFiles += $filePath }
|
|
"D" { $deletedFiles += $filePath }
|
|
"R*" {
|
|
# Rename: stary plik = deleted, nowy = added
|
|
$newPath = if ($parts.Count -gt 2) { $parts[2] -replace '\\', '/' } else { "" }
|
|
$deletedFiles += $filePath
|
|
if ($newPath) { $addedFiles += $newPath }
|
|
}
|
|
}
|
|
}
|
|
|
|
Write-Step "Zmiany: A=$($addedFiles.Count), M=$($modifiedFiles.Count), D=$($deletedFiles.Count)"
|
|
|
|
# --- 4. Filtrowanie przez .updateignore ---
|
|
|
|
$ignorePatterns = @()
|
|
$ignoreFile = ".updateignore"
|
|
|
|
if (Test-Path $ignoreFile) {
|
|
$ignorePatterns = Get-Content $ignoreFile | ForEach-Object { $_.Trim() } | Where-Object { $_ -and ($_ -notmatch '^\s*#') }
|
|
Write-Step "Zaladowano $($ignorePatterns.Count) wzorcow z .updateignore"
|
|
}
|
|
|
|
function Test-Ignored {
|
|
param([string]$FilePath)
|
|
|
|
foreach ($pattern in $ignorePatterns) {
|
|
# Wzorzec katalogu (konczy sie na /)
|
|
if ($pattern.EndsWith('/')) {
|
|
$dirPattern = $pattern.TrimEnd('/')
|
|
if ($FilePath -like "$dirPattern/*" -or $FilePath -eq $dirPattern) {
|
|
return $true
|
|
}
|
|
}
|
|
# Wzorzec z wildcard
|
|
elseif ($pattern.Contains('*')) {
|
|
# *.md -> dopasuj nazwe pliku
|
|
if ($pattern.StartsWith('*')) {
|
|
$fileName = Split-Path $FilePath -Leaf
|
|
if ($fileName -like $pattern) { return $true }
|
|
}
|
|
# Zwykly glob
|
|
elseif ($FilePath -like $pattern) { return $true }
|
|
}
|
|
# Dokladne dopasowanie
|
|
else {
|
|
if ($FilePath -eq $pattern) { return $true }
|
|
}
|
|
}
|
|
return $false
|
|
}
|
|
|
|
$filteredAdded = @()
|
|
$filteredModified = @()
|
|
$filteredDeleted = @()
|
|
$ignoredCount = 0
|
|
|
|
foreach ($f in $addedFiles) {
|
|
if (Test-Ignored $f) { $ignoredCount++; continue }
|
|
$filteredAdded += $f
|
|
}
|
|
foreach ($f in $modifiedFiles) {
|
|
if (Test-Ignored $f) { $ignoredCount++; continue }
|
|
$filteredModified += $f
|
|
}
|
|
foreach ($f in $deletedFiles) {
|
|
if (Test-Ignored $f) { $ignoredCount++; continue }
|
|
$filteredDeleted += $f
|
|
}
|
|
|
|
Write-Step "Po filtrowaniu: A=$($filteredAdded.Count), M=$($filteredModified.Count), D=$($filteredDeleted.Count) (pominieto: $ignoredCount)"
|
|
|
|
# Rozdziel usuniete pliki i katalogi
|
|
$deletedDirs = @()
|
|
$deletedFilesOnly = @()
|
|
|
|
foreach ($f in $filteredDeleted) {
|
|
# Git nie trackuje pustych katalogow, wiec deleted entries to zawsze pliki
|
|
$deletedFilesOnly += $f
|
|
}
|
|
|
|
# --- 5. Odczyt migracji SQL ---
|
|
|
|
$sqlQueries = @()
|
|
$migrationFile = "migrations/$versionNumber.sql"
|
|
|
|
if (Test-Path $migrationFile) {
|
|
$sqlQueries = @(Get-Content $migrationFile | Where-Object { $_.Trim() -ne '' } | ForEach-Object { $_.ToString() })
|
|
Write-Step "Znaleziono migracje SQL: $migrationFile ($($sqlQueries.Count) zapytan)"
|
|
} else {
|
|
Write-Step "Brak migracji SQL ($migrationFile nie istnieje)"
|
|
}
|
|
|
|
# --- 6. Podsumowanie ---
|
|
|
|
$filesToPack = $filteredAdded + $filteredModified
|
|
|
|
if ($filesToPack.Count -eq 0 -and $filteredDeleted.Count -eq 0 -and $sqlQueries.Count -eq 0) {
|
|
Write-Warn "Brak zmian do pakowania (po filtrowaniu). Przerywam."
|
|
exit 0
|
|
}
|
|
|
|
Write-Host "`n--- Pliki do paczki ---" -ForegroundColor White
|
|
foreach ($f in $filteredAdded) { Write-Host " A $f" -ForegroundColor Green }
|
|
foreach ($f in $filteredModified) { Write-Host " M $f" -ForegroundColor Yellow }
|
|
foreach ($f in $filteredDeleted) { Write-Host " D $f" -ForegroundColor Red }
|
|
|
|
if ($sqlQueries.Count -gt 0) {
|
|
Write-Host "`n--- SQL ---" -ForegroundColor White
|
|
foreach ($q in $sqlQueries) { Write-Host " $q" -ForegroundColor Gray }
|
|
}
|
|
|
|
# --- DryRun? ---
|
|
|
|
if ($DryRun) {
|
|
Write-Host "`n[DRY RUN] Zadne pliki nie zostaly utworzone.`n" -ForegroundColor Magenta
|
|
exit 0
|
|
}
|
|
|
|
# --- 7. Walidacja ChangelogEntry ---
|
|
|
|
if (-not $ChangelogEntry) {
|
|
Write-Err "Parametr -ChangelogEntry jest wymagany (chyba ze uzywasz -DryRun)."
|
|
exit 1
|
|
}
|
|
|
|
# --- 8. Tworzenie temp i kopiowanie plikow ---
|
|
|
|
$tempDir = "temp/temp_$versionInt"
|
|
|
|
if (Test-Path $tempDir) {
|
|
Remove-Item -Recurse -Force $tempDir
|
|
}
|
|
|
|
foreach ($f in $filesToPack) {
|
|
$destPath = Join-Path $tempDir $f
|
|
$destDir = Split-Path $destPath -Parent
|
|
|
|
if (-not (Test-Path $destDir)) {
|
|
New-Item -ItemType Directory -Path $destDir -Force | Out-Null
|
|
}
|
|
|
|
if (Test-Path $f) {
|
|
Copy-Item $f $destPath -Force
|
|
} else {
|
|
Write-Warn "Plik nie istnieje (moze zostal usuniety po TAGU): $f"
|
|
}
|
|
}
|
|
|
|
Write-Ok "Skopiowano $($filesToPack.Count) plikow do $tempDir"
|
|
|
|
# --- 9. Tworzenie ZIP ---
|
|
|
|
$updatesDir = "updates/$dirStr"
|
|
if (-not (Test-Path $updatesDir)) {
|
|
New-Item -ItemType Directory -Path $updatesDir -Force | Out-Null
|
|
}
|
|
|
|
$zipPath = "$updatesDir/ver_$versionNumber.zip"
|
|
|
|
if (Test-Path $zipPath) {
|
|
Remove-Item $zipPath -Force
|
|
}
|
|
|
|
# Pakuj zawartosc temp dir (bez folderu temp/)
|
|
$originalLocation = Get-Location
|
|
Set-Location $tempDir
|
|
Compress-Archive -Path '*' -DestinationPath "../../$zipPath" -Force
|
|
Set-Location $originalLocation
|
|
|
|
Write-Ok "Utworzono ZIP: $zipPath"
|
|
|
|
# --- 10. Checksum SHA256 ---
|
|
|
|
$hash = (Get-FileHash $zipPath -Algorithm SHA256).Hash.ToLower()
|
|
Write-Ok "SHA256: $hash"
|
|
|
|
# --- 11. Manifest JSON ---
|
|
|
|
$manifest = @{
|
|
version = $versionNumber
|
|
date = (Get-Date -Format "yyyy-MM-dd")
|
|
checksum_zip = "sha256:$hash"
|
|
files = @{
|
|
modified = $filteredModified
|
|
added = $filteredAdded
|
|
deleted = $deletedFilesOnly
|
|
}
|
|
directories_deleted = $deletedDirs
|
|
sql = $sqlQueries
|
|
changelog = $ChangelogEntry
|
|
}
|
|
|
|
$manifestJson = $manifest | ConvertTo-Json -Depth 4
|
|
$manifestPath = "$updatesDir/ver_${versionNumber}_manifest.json"
|
|
[System.IO.File]::WriteAllText($manifestPath, $manifestJson, $Utf8NoBom)
|
|
|
|
Write-Ok "Utworzono manifest: $manifestPath"
|
|
|
|
# --- 12. Legacy _sql.txt i _files.txt (okres przejsciowy) ---
|
|
|
|
if ($sqlQueries.Count -gt 0) {
|
|
$sqlPath = "$updatesDir/ver_${versionNumber}_sql.txt"
|
|
[System.IO.File]::WriteAllText($sqlPath, ($sqlQueries -join "`n"), $Utf8NoBom)
|
|
Write-Ok "Utworzono legacy SQL: $sqlPath"
|
|
}
|
|
|
|
if ($deletedFilesOnly.Count -gt 0 -or $deletedDirs.Count -gt 0) {
|
|
$filesContent = @()
|
|
foreach ($f in $deletedFilesOnly) { $filesContent += "F: ../$f" }
|
|
foreach ($d in $deletedDirs) { $filesContent += "D: ../$d" }
|
|
|
|
$filesPath = "$updatesDir/ver_${versionNumber}_files.txt"
|
|
[System.IO.File]::WriteAllText($filesPath, ($filesContent -join "`n"), $Utf8NoBom)
|
|
Write-Ok "Utworzono legacy files: $filesPath"
|
|
}
|
|
|
|
# --- 13. Aktualizacja versions.php ---
|
|
|
|
$versionsFile = "updates/versions.php"
|
|
if (Test-Path $versionsFile) {
|
|
$content = Get-Content $versionsFile -Raw
|
|
$content = $content -replace '\$current_ver\s*=\s*\d+;', "`$current_ver = $versionInt;"
|
|
[System.IO.File]::WriteAllText($versionsFile, $content, $Utf8NoBom)
|
|
Write-Ok "Zaktualizowano versions.php: `$current_ver = $versionInt"
|
|
}
|
|
|
|
# --- 14. Cleanup ---
|
|
|
|
if (Test-Path $tempDir) {
|
|
Remove-Item -Recurse -Force $tempDir
|
|
}
|
|
# Usun pusty folder temp jesli nie ma juz w nim nic
|
|
if ((Test-Path "temp") -and ((Get-ChildItem "temp" -Force).Count -eq 0)) {
|
|
Remove-Item "temp" -Force
|
|
}
|
|
|
|
Write-Ok "Wyczyszczono pliki tymczasowe"
|
|
|
|
# --- Podsumowanie ---
|
|
|
|
Write-Host "`n=== Gotowe ===" -ForegroundColor Green
|
|
Write-Host " ZIP: $zipPath"
|
|
Write-Host " Manifest: $manifestPath"
|
|
Write-Host " Wersja: $versionNumber (int: $versionInt)"
|
|
Write-Host ""
|